forked from pierront/mylibrary-template
Compare commits
12 Commits
276b6e4fc6
...
main
Author | SHA1 | Date | |
---|---|---|---|
c0599b91c9 | |||
fa30672977 | |||
3b42e4aaf9 | |||
81ae9faba6 | |||
e3f6f30fb6 | |||
bfefc92360 | |||
2a5cbbd745 | |||
d5049671e6 | |||
d522d0dad1 | |||
7d31067021 | |||
219b924efa | |||
e06a0b3b3c |
@@ -5,7 +5,7 @@ import java.util.UUID;
|
||||
|
||||
public class BookNotFoundException extends Exception {
|
||||
|
||||
public static final String THE_BOOK_WITH_ISBN_DOES_NOT_EXIST_MESSAGE = "The book with ISBN {0} does not exist";
|
||||
public static final String THE_BOOK_WITH_ISBN_DOES_NOT_EXIST_MESSAGE = "Book not found: {0}";
|
||||
|
||||
public BookNotFoundException(String isbn) {
|
||||
super(MessageFormat.format(THE_BOOK_WITH_ISBN_DOES_NOT_EXIST_MESSAGE, isbn));
|
||||
|
@@ -4,7 +4,7 @@ import java.text.MessageFormat;
|
||||
|
||||
public class IllegalBookStockException extends Exception {
|
||||
|
||||
public static final String CANNOT_REMOVE_STOCK = "Cannot remove {0} stock from {1} points";
|
||||
public static final String CANNOT_REMOVE_STOCK = "Cannot remove {0} stock from {1} stock";
|
||||
|
||||
public IllegalBookStockException(int needed, int actual) {
|
||||
super(MessageFormat.format(CANNOT_REMOVE_STOCK, needed,
|
||||
|
@@ -7,6 +7,8 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
|
||||
@NoArgsConstructor
|
||||
public final class BookRepository {
|
||||
private final List<Book> books = new ArrayList<>();
|
||||
@@ -20,17 +22,24 @@ public final class BookRepository {
|
||||
}
|
||||
|
||||
public Book save(Book newBook) {
|
||||
Optional<Book> optionalBookWithSameId = this.findByISBN(newBook.getIsbn());
|
||||
optionalBookWithSameId.ifPresent(books::remove);
|
||||
for (Book book: books) {
|
||||
if (book.getIsbn().equals(newBook.getIsbn())){
|
||||
books.remove(book);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.books.add(newBook);
|
||||
return newBook;
|
||||
}
|
||||
|
||||
public Optional<Book> findByISBN(String isbn) {
|
||||
|
||||
return this.books.stream()
|
||||
.filter(book -> book.getIsbn().equals(isbn))
|
||||
.findFirst();
|
||||
for (Book book:books) {
|
||||
System.out.println(book.getIsbn());
|
||||
if(book.getIsbn().equals(isbn)){
|
||||
return Optional.of(book);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public boolean existsByISBN(String isbn) {
|
||||
|
@@ -23,11 +23,12 @@ public final class BookUseCase {
|
||||
public String registerBook(BookInfo newBook) throws NotValidBookException {
|
||||
BookValidator.validate(newBook);
|
||||
Book bookToRegister = BookConverter.toDomain(newBook);
|
||||
Book bookToRegistered = bookRepository.save(bookToRegister);
|
||||
return bookToRegistered.getIsbn();
|
||||
bookRepository.save(bookToRegister);
|
||||
return bookToRegister.getIsbn();
|
||||
}
|
||||
|
||||
public Optional<BookDTO> findBookByISBN(String isbn) {
|
||||
System.out.println(bookRepository.findAll().size());
|
||||
Optional<Book> optionalBook = bookRepository.findByISBN(isbn);
|
||||
return optionalBook.map(BookConverter::toDTO);
|
||||
}
|
||||
|
@@ -24,7 +24,10 @@ public final class BookValidator {
|
||||
public static void validate(BookInfo newBook) throws NotValidBookException {
|
||||
validateAuthor(newBook);
|
||||
validateTitle(newBook);
|
||||
validatePublisher(newBook);
|
||||
validateISBN(newBook);
|
||||
validatePrice(newBook);
|
||||
validateInitialStock(newBook);
|
||||
}
|
||||
|
||||
private static void validateISBN(BookInfo newBook)
|
||||
|
@@ -20,15 +20,23 @@ public final class CustomerRepository {
|
||||
}
|
||||
|
||||
public Customer save(Customer newCustomer) {
|
||||
Optional<Customer> optionalCustomerWithSameId = this.findById(newCustomer.getId());
|
||||
optionalCustomerWithSameId.ifPresentOrElse(customers::remove, newCustomer::setRandomUUID);
|
||||
if (newCustomer.getId() == null) {
|
||||
newCustomer.setRandomUUID();
|
||||
}
|
||||
|
||||
this.findById(newCustomer.getId()).ifPresent(customers::remove);
|
||||
|
||||
this.customers.add(newCustomer);
|
||||
return newCustomer;
|
||||
}
|
||||
|
||||
public Optional<Customer> findById(UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return this.customers.stream()
|
||||
.filter(customer -> customer.getId().equals(uuid))
|
||||
.filter(customer -> uuid.equals(customer.getId()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,13 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class AddressDTO {
|
||||
private final String street;
|
||||
private final String city;
|
||||
private final String postalCode;
|
||||
private final String country;
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class OrderDTO {
|
||||
private final UUID id;
|
||||
private final UUID customerId;
|
||||
private final List<OrderLineDTO> orderLines;
|
||||
private final double totalPrice;
|
||||
private final double totalPriceToPay;
|
||||
private final AddressDTO address;
|
||||
private final PaymentMethod paymentMethod;
|
||||
}
|
@@ -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,11 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class OrderLineDTO {
|
||||
private final String bookId;
|
||||
private final int quantity;
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order;
|
||||
|
||||
public enum PaymentMethod {
|
||||
CREDIT_CARD,
|
||||
LOYALTY_POINTS
|
||||
}
|
@@ -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,27 @@
|
||||
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 lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Setter
|
||||
@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();
|
||||
}
|
||||
}
|
@@ -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,9 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||
|
||||
public class UserNotFoundException extends RuntimeException {
|
||||
|
||||
public UserNotFoundException(String message) {
|
||||
super(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,193 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.IllegalBookStockException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.IllegalCustomerPointException;
|
||||
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, BookNotFoundException, IllegalBookStockException, IllegalCustomerPointException {
|
||||
// Validation des données d'entrée
|
||||
OrderInfo completeInfo = validateAndBuildOrderInfo();
|
||||
|
||||
// Récupération du client
|
||||
Customer customer = customerRepository.findById(completeInfo.getCustomerId())
|
||||
.orElseThrow(() -> new UserNotFoundException("Client introuvable"));
|
||||
|
||||
// Traitement des livres et calcul du prix
|
||||
double totalPrice = processOrderLines(completeInfo.getOrderLines());
|
||||
|
||||
// Gestion du paiement
|
||||
handlePayment(completeInfo, customer, totalPrice);
|
||||
|
||||
// Création et sauvegarde de la commande
|
||||
UUID orderId = createAndSaveOrder(completeInfo, totalPrice);
|
||||
|
||||
// Nettoyage des données temporaires
|
||||
resetTempData();
|
||||
|
||||
return orderId;
|
||||
}
|
||||
|
||||
private OrderInfo validateAndBuildOrderInfo() throws NotValidOrderException, BookNotFoundException {
|
||||
if (tempOrderInfo == null) throw new NotValidOrderException("Order info missing");
|
||||
OrderInfo completeInfo = OrderInfo.builder()
|
||||
.customerId(tempOrderInfo.getCustomerId())
|
||||
.paymentMethod(tempOrderInfo.getPaymentMethod())
|
||||
.orderLines(tempOrderLines)
|
||||
.address(tempAddress)
|
||||
.build();
|
||||
|
||||
// Validation centralisée
|
||||
OrderValidator.validate(completeInfo, bookRepository, customerRepository);
|
||||
return completeInfo;
|
||||
}
|
||||
|
||||
private double processOrderLines(List<OrderLineDTO> orderLines) throws BookNotFoundException, IllegalBookStockException {
|
||||
double totalPrice = 0.0;
|
||||
for (OrderLineDTO line : orderLines) {
|
||||
Book book = getBookOrThrow(line.getBookId());
|
||||
updateBookStock(book, line.getQuantity());
|
||||
totalPrice += calculateLinePrice(book, line.getQuantity());
|
||||
}
|
||||
return totalPrice;
|
||||
}
|
||||
|
||||
private Book getBookOrThrow(String bookId) throws BookNotFoundException {
|
||||
return bookRepository.findByISBN(bookId)
|
||||
.orElseThrow(() -> new BookNotFoundException("Livre non trouvé: " + bookId));
|
||||
}
|
||||
|
||||
private void updateBookStock(Book book, int quantity) throws IllegalBookStockException {
|
||||
book.removeStock(quantity);
|
||||
bookRepository.save(book);
|
||||
}
|
||||
|
||||
private double calculateLinePrice(Book book, int quantity) {
|
||||
return book.getPrice() * quantity;
|
||||
}
|
||||
|
||||
private void handlePayment(OrderInfo orderInfo, Customer customer, double totalPrice) throws IllegalCustomerPointException {
|
||||
if (isLoyaltyPointsPayment(orderInfo)) {
|
||||
deductLoyaltyPoints(customer, totalPrice);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isLoyaltyPointsPayment(OrderInfo orderInfo) {
|
||||
return "LOYALTY_POINTS".equalsIgnoreCase(orderInfo.getPaymentMethod());
|
||||
}
|
||||
|
||||
private void deductLoyaltyPoints(Customer customer, double totalPrice) throws IllegalCustomerPointException {
|
||||
int pointsToDeduct = (int) Math.round(totalPrice);
|
||||
customer.removeLoyaltyPoints(pointsToDeduct);
|
||||
customerRepository.save(customer);
|
||||
}
|
||||
|
||||
private UUID createAndSaveOrder(OrderInfo orderInfo, double totalPrice) throws NotValidOrderException {
|
||||
Order order = OrderConverter.toDomain(orderInfo);
|
||||
order.setRandomUUID();
|
||||
order.setAddress(tempAddress);
|
||||
order.setOrderLines(tempOrderLines);
|
||||
order.setTotalPrice(totalPrice);
|
||||
order.setTotalPriceToPay(totalPrice);
|
||||
|
||||
orderRepository.save(order);
|
||||
return order.getId();
|
||||
}
|
||||
|
||||
private void resetTempData() {
|
||||
tempOrderInfo = null;
|
||||
tempOrderLines = null;
|
||||
tempAddress = null;
|
||||
}
|
||||
|
||||
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 {
|
||||
ensureCustomerExists(customerId);
|
||||
List<Order> orders = orderRepository.findByCustomerId(customerId);
|
||||
return orders.stream().map(OrderConverter::toDTO).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void ensureCustomerExists(UUID customerId) throws UserNotFoundException {
|
||||
if (!customerRepository.findById(customerId).isPresent()) {
|
||||
throw new UserNotFoundException("Customer not found");
|
||||
}
|
||||
}
|
||||
|
||||
public UUID registerOrder(OrderInfo orderInfo) throws NotValidOrderException, UserNotFoundException, BookNotFoundException {
|
||||
OrderValidator.validate(orderInfo, bookRepository, customerRepository);
|
||||
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,135 @@
|
||||
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 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 fr.iut_fbleau.but3.dev62.mylibrary.order.exception.UserNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
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";
|
||||
public static final String PAYMENT_METHOD_IS_NOT_VALID = "Payment method is not valid";
|
||||
|
||||
private OrderValidator() {
|
||||
|
||||
}
|
||||
|
||||
public static void validate(OrderInfo orderInfo, BookRepository bookRepository, CustomerRepository customerRepository)
|
||||
throws NotValidOrderException, UserNotFoundException, BookNotFoundException {
|
||||
validateCustomerId(orderInfo);
|
||||
Customer customer = validateCustomerExistence(orderInfo, customerRepository);
|
||||
double totalPrice = validateBooksAndStock(orderInfo, bookRepository);
|
||||
validateOrderLines(orderInfo);
|
||||
validateAddress(orderInfo);
|
||||
validatePaymentMethod(orderInfo);
|
||||
validateLoyaltyPoints(orderInfo, customer, totalPrice);
|
||||
}
|
||||
|
||||
private static Customer validateCustomerExistence(OrderInfo orderInfo, CustomerRepository customerRepository)
|
||||
throws UserNotFoundException {
|
||||
Customer customer = customerRepository.findById(orderInfo.getCustomerId()).orElse(null);
|
||||
if (customer == null) {
|
||||
throw new UserNotFoundException("Customer not found");
|
||||
}
|
||||
return customer;
|
||||
}
|
||||
|
||||
private static double validateBooksAndStock(OrderInfo orderInfo, BookRepository bookRepository)
|
||||
throws BookNotFoundException, NotValidOrderException {
|
||||
double totalPrice = 0.0;
|
||||
for (OrderLineDTO line : orderInfo.getOrderLines()) {
|
||||
Book book = getBookOrThrow(line, bookRepository);
|
||||
validateQuantityPositive(line);
|
||||
validateStockSufficient(book, line);
|
||||
totalPrice += book.getPrice() * line.getQuantity();
|
||||
}
|
||||
return totalPrice;
|
||||
}
|
||||
|
||||
private static Book getBookOrThrow(OrderLineDTO line, BookRepository bookRepository) throws BookNotFoundException {
|
||||
Book book = bookRepository.findByISBN(line.getBookId()).orElse(null);
|
||||
if (book == null) {
|
||||
throw new BookNotFoundException(line.getBookId());
|
||||
}
|
||||
return book;
|
||||
}
|
||||
|
||||
private static void validateQuantityPositive(OrderLineDTO line) throws NotValidOrderException {
|
||||
if (line.getQuantity() <= 0) {
|
||||
throw new NotValidOrderException(QUANTITY_MUST_BE_POSITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateStockSufficient(Book book, OrderLineDTO line) throws NotValidOrderException {
|
||||
if (book.getInitialStock() < line.getQuantity()) {
|
||||
throw new NotValidOrderException("Insufficient book stock");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateLoyaltyPoints(OrderInfo orderInfo, Customer customer, double totalPrice)
|
||||
throws NotValidOrderException {
|
||||
if ("LOYALTY_POINTS".equalsIgnoreCase(orderInfo.getPaymentMethod())) {
|
||||
int pointsToDeduct = (int) Math.round(totalPrice);
|
||||
if (customer.getLoyaltyPoints() < pointsToDeduct) {
|
||||
throw new NotValidOrderException("Not enough loyalty points");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
validateOrderLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateOrderLine(OrderLineDTO line) throws NotValidOrderException {
|
||||
validateQuantityPositive(line);
|
||||
}
|
||||
|
||||
private static void validateAddress(OrderInfo orderInfo) throws NotValidOrderException {
|
||||
AddressDTO address = orderInfo.getAddress();
|
||||
if (address == null) {
|
||||
throw new NotValidOrderException(ADDRESS_FIELDS_ARE_REQUIRED);
|
||||
}
|
||||
validateAddressFields(address);
|
||||
}
|
||||
|
||||
private static void validateAddressFields(AddressDTO address) throws NotValidOrderException {
|
||||
if (isBlank(address.getStreet()) || isBlank(address.getCity()) || isBlank(address.getPostalCode()) || isBlank(address.getCountry())) {
|
||||
throw new NotValidOrderException(ADDRESS_FIELDS_ARE_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBlank(String value) {
|
||||
return value == null || value.isBlank();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class ReviewDto {
|
||||
private final UUID reviewId;
|
||||
private final String bookId; // Changed from long to String
|
||||
private final String customerName;
|
||||
private final String comment;
|
||||
private final int rating;
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class ReviewInfo {
|
||||
private final String customerId;
|
||||
private final String isbn; // Changed from long to String
|
||||
private final int rating;
|
||||
private final String comment;
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.converter;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.ReviewDto;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.ReviewInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.entity.Review;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ReviewConverter {
|
||||
public static ReviewDto toDto(Review review, UUID reviewId, String customerName) {
|
||||
return ReviewDto.builder()
|
||||
.reviewId(reviewId)
|
||||
.bookId(review.getIsbn()) // Changed from long to String
|
||||
.customerName(customerName)
|
||||
.comment(review.getComment())
|
||||
.rating(review.getRating())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Review toDomain(ReviewInfo info) {
|
||||
return Review.builder()
|
||||
.customerId(UUID.fromString(info.getCustomerId()))
|
||||
.isbn(info.getIsbn()) // Changed from long to String
|
||||
.rating(info.getRating())
|
||||
.comment(info.getComment())
|
||||
.build();
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Review {
|
||||
private UUID customerId;
|
||||
private String isbn; // Changed from long to String
|
||||
private int rating;
|
||||
private String comment;
|
||||
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.exception;
|
||||
|
||||
public class InvalidReviewRatingException extends RuntimeException {
|
||||
public InvalidReviewRatingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,7 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.exception;
|
||||
|
||||
public class NotValidReviewException extends Exception {
|
||||
public NotValidReviewException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.exception;
|
||||
|
||||
public class ReviewAlreadyExistsException extends RuntimeException {
|
||||
public ReviewAlreadyExistsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,8 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.exception;
|
||||
|
||||
public class ReviewNotFoundException extends RuntimeException {
|
||||
public ReviewNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,43 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.entity.Review;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ReviewRepository {
|
||||
private final List<Review> reviews = new ArrayList<>();
|
||||
|
||||
public void save(Review review) {
|
||||
reviews.add(review);
|
||||
}
|
||||
|
||||
public List<Review> findAll() {
|
||||
return new ArrayList<>(reviews);
|
||||
}
|
||||
|
||||
public List<Review> findByIsbn(String isbn) { // Changed from long to String
|
||||
return reviews.stream().filter(r -> r.getIsbn().equals(isbn)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Review> findByCustomerId(UUID customerId) {
|
||||
return reviews.stream().filter(r -> r.getCustomerId().equals(customerId)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public boolean existsByCustomerIdAndIsbn(UUID customerId, String isbn) { // Changed from long to String
|
||||
return reviews.stream().anyMatch(r -> r.getCustomerId().equals(customerId) && r.getIsbn().equals(isbn));
|
||||
}
|
||||
|
||||
public void deleteByCustomerIdAndIsbn(UUID customerId, String isbn) { // Changed from long to String
|
||||
reviews.removeIf(r -> r.getCustomerId().equals(customerId) && r.getIsbn().equals(isbn));
|
||||
}
|
||||
|
||||
public void update(Review review) {
|
||||
deleteByCustomerIdAndIsbn(review.getCustomerId(), review.getIsbn());
|
||||
save(review);
|
||||
}
|
||||
|
||||
public void deleteAll() {
|
||||
reviews.clear();
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.entity.Review;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.exception.InvalidReviewRatingException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.exception.ReviewAlreadyExistsException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.exception.ReviewNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.CustomerNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.repository.ReviewRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.validator.ReviewValidator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ReviewUseCase {
|
||||
private final ReviewRepository reviewRepository;
|
||||
private final BookRepository bookRepository;
|
||||
private final CustomerRepository customerRepository;
|
||||
|
||||
public ReviewUseCase(ReviewRepository reviewRepository, BookRepository bookRepository, CustomerRepository customerRepository) {
|
||||
this.reviewRepository = reviewRepository;
|
||||
this.bookRepository = bookRepository;
|
||||
this.customerRepository = customerRepository;
|
||||
}
|
||||
|
||||
public void submitReview(Review review) throws CustomerNotFoundException, BookNotFoundException {
|
||||
ReviewValidator.validate(review);
|
||||
|
||||
System.out.println(bookRepository.existsByISBN(review.getIsbn()));
|
||||
System.out.println(customerRepository.existsById(review.getCustomerId()));
|
||||
System.out.println(customerRepository.findById(review.getCustomerId()));
|
||||
System.out.println(reviewRepository.existsByCustomerIdAndIsbn(review.getCustomerId(), review.getIsbn()));
|
||||
|
||||
if (!bookRepository.existsByISBN(review.getIsbn())) {
|
||||
throw new BookNotFoundException(review.getIsbn());
|
||||
}
|
||||
|
||||
if (!customerRepository.existsById(review.getCustomerId())) {
|
||||
throw new CustomerNotFoundException(review.getCustomerId());
|
||||
}
|
||||
|
||||
if (reviewRepository.existsByCustomerIdAndIsbn(review.getCustomerId(), review.getIsbn())) {
|
||||
throw new ReviewAlreadyExistsException("Review already exists for this customer and book.");
|
||||
}
|
||||
|
||||
reviewRepository.save(review);
|
||||
}
|
||||
|
||||
public List<Review> getReviewsByBook(String isbn) { // Changed from long to String
|
||||
return reviewRepository.findByIsbn(isbn);
|
||||
}
|
||||
|
||||
public List<Review> getReviewsByCustomer(UUID customerId) {
|
||||
return reviewRepository.findByCustomerId(customerId);
|
||||
}
|
||||
|
||||
public void updateReview(Review review) {
|
||||
ReviewValidator.validate(review);
|
||||
if (!reviewRepository.existsByCustomerIdAndIsbn(review.getCustomerId(), review.getIsbn())) { // Changed from long to String
|
||||
throw new ReviewNotFoundException("Review not found for this customer and book.");
|
||||
}
|
||||
reviewRepository.update(review);
|
||||
}
|
||||
|
||||
public void deleteReview(String isbn, UUID customerId) { // Changed from long to String
|
||||
if (!reviewRepository.existsByCustomerIdAndIsbn(customerId, isbn)) { // Changed from long to String
|
||||
throw new ReviewNotFoundException("Review not found for this customer and book.");
|
||||
}
|
||||
reviewRepository.deleteByCustomerIdAndIsbn(customerId, isbn);
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.entity.Review;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.exception.InvalidReviewRatingException;
|
||||
|
||||
public class ReviewValidator {
|
||||
public static final String ISBN_IS_NOT_VALID = "ISBN must be a valid 13-digit string";
|
||||
|
||||
public static void validate(Review review) {
|
||||
validateReviewNotNull(review);
|
||||
validateRating(review);
|
||||
validateComment(review);
|
||||
validateCustomerId(review);
|
||||
validateBookIsbn(review);
|
||||
}
|
||||
|
||||
private static void validateReviewNotNull(Review review) throws IllegalArgumentException {
|
||||
if (review == null) {
|
||||
throw new IllegalArgumentException("Review cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateRating(Review review) throws InvalidReviewRatingException {
|
||||
if (review.getRating() < 1 || review.getRating() > 5) {
|
||||
throw new InvalidReviewRatingException("Rating must be between 1 and 5");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateComment(Review review) throws IllegalArgumentException {
|
||||
if (review.getComment() == null || review.getComment().trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("Comment cannot be empty");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateCustomerId(Review review) throws IllegalArgumentException {
|
||||
if (review.getCustomerId() == null) {
|
||||
throw new IllegalArgumentException("Customer ID cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateBookIsbn(Review review) throws IllegalArgumentException {
|
||||
if (review.getIsbn() == null || !review.getIsbn().matches("\\d{13}")) {
|
||||
throw new IllegalArgumentException(ISBN_IS_NOT_VALID);
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,8 +5,9 @@ import java.util.UUID;
|
||||
|
||||
public class SubscriptionNotFoundException extends Exception {
|
||||
|
||||
public static final String THE_SUBSCRIPTION_WITH_ID_DOES_NOT_EXIST_MESSAGE = "The customer with id {0} does not exist";
|
||||
public static final String THE_SUBSCRIPTION_WITH_ID_DOES_NOT_EXIST_MESSAGE = "The subscription with id {0} does not exist";
|
||||
|
||||
public SubscriptionNotFoundException(UUID uuid) {
|
||||
super(MessageFormat.format(THE_SUBSCRIPTION_WITH_ID_DOES_NOT_EXIST_MESSAGE, uuid));
|
||||
super(MessageFormat.format(THE_SUBSCRIPTION_WITH_ID_DOES_NOT_EXIST_MESSAGE, uuid));
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,12 @@ public class SubscriptionRepository {
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public Optional<Subscription> findById(UUID id) {
|
||||
return this.subscriptions.stream()
|
||||
.filter(subscription -> subscription.getId().equals(id))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public boolean existsById(UUID uuid) {
|
||||
return this.subscriptions.stream()
|
||||
.anyMatch(subscription -> subscription.getId().equals(uuid));
|
||||
|
@@ -17,19 +17,25 @@ public class SubscriptionValidator {
|
||||
|
||||
}
|
||||
|
||||
public static void validate(SubscriptionInfo newSubscription) throws fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException {
|
||||
public static void validate(SubscriptionInfo newSubscription) throws NotValidSubscriptionException {
|
||||
validateCustomerId(newSubscription);
|
||||
validateDuration(newSubscription);
|
||||
validatePaymentMethod(newSubscription);
|
||||
}
|
||||
|
||||
|
||||
private static void validateDuration(SubscriptionInfo newSubscription) throws fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException {
|
||||
if (newSubscription.duration() == null) {
|
||||
throw new fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException(DURATION_CANNOT_BE_NULL);
|
||||
private static void validateCustomerId(SubscriptionInfo newSubscription) throws NotValidSubscriptionException {
|
||||
if (newSubscription.customerId() == null) {
|
||||
throw new NotValidSubscriptionException(CUSTOMER_ID_CANNOT_BE_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePaymentMethod(SubscriptionInfo newSubscription) throws fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException {
|
||||
private static void validateDuration(SubscriptionInfo newSubscription) throws NotValidSubscriptionException {
|
||||
if (newSubscription.duration() == null) {
|
||||
throw new NotValidSubscriptionException(DURATION_CANNOT_BE_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePaymentMethod(SubscriptionInfo newSubscription) throws NotValidSubscriptionException {
|
||||
if (newSubscription.paymentMethod().isBlank()) {
|
||||
throw new NotValidSubscriptionException(PAYMENT_METHOD_CANNOT_BE_BLANK);
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ class BookRepositoryTest {
|
||||
assertEquals(book1.getTitle(), savedBook.getTitle());
|
||||
assertEquals(book1.getAuthor(), savedBook.getAuthor());
|
||||
assertEquals(book1.getPublisher(), savedBook.getPublisher());
|
||||
assertEquals(book1, savedBook.getDate());
|
||||
assertEquals(book1.getDate(), savedBook.getDate());
|
||||
assertEquals(book1.getPrice(), savedBook.getPrice());
|
||||
assertEquals(book1.getInitialStock(), savedBook.getInitialStock());
|
||||
assertEquals(book1.getCategories(), savedBook.getCategories());
|
||||
@@ -103,16 +103,16 @@ class BookRepositoryTest {
|
||||
Book savedBook = repository.save(updatedBook);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertEquals(book1.getIsbn(), savedBook.getIsbn());
|
||||
assertEquals(book1.getTitle(), savedBook.getTitle());
|
||||
assertEquals(book1.getAuthor(), savedBook.getAuthor());
|
||||
assertEquals(book1.getPublisher(), savedBook.getPublisher());
|
||||
assertEquals(book1, savedBook.getDate());
|
||||
assertEquals(book1.getPrice(), savedBook.getPrice());
|
||||
assertEquals(book1.getInitialStock(), savedBook.getInitialStock());
|
||||
assertEquals(book1.getCategories(), savedBook.getCategories());
|
||||
assertEquals(book1.getDescription(), savedBook.getDescription());
|
||||
assertEquals(book1.getLanguage(), savedBook.getLanguage());
|
||||
assertEquals(updatedBook.getIsbn(), savedBook.getIsbn());
|
||||
assertEquals(updatedBook.getTitle(), savedBook.getTitle());
|
||||
assertEquals(updatedBook.getAuthor(), savedBook.getAuthor());
|
||||
assertEquals(updatedBook.getPublisher(), savedBook.getPublisher());
|
||||
assertEquals(updatedBook.getDate(), savedBook.getDate());
|
||||
assertEquals(updatedBook.getPrice(), savedBook.getPrice());
|
||||
assertEquals(updatedBook.getInitialStock(), savedBook.getInitialStock());
|
||||
assertEquals(updatedBook.getCategories(), savedBook.getCategories());
|
||||
assertEquals(updatedBook.getDescription(), savedBook.getDescription());
|
||||
assertEquals(updatedBook.getLanguage(), savedBook.getLanguage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -159,7 +159,7 @@ class BookRepositoryTest {
|
||||
assertEquals(book1.getTitle(), foundBook.get().getTitle());
|
||||
assertEquals(book1.getAuthor(), foundBook.get().getAuthor());
|
||||
assertEquals(book1.getPublisher(), foundBook.get().getPublisher());
|
||||
assertEquals(book1, foundBook.get().getDate());
|
||||
assertEquals(book1.getDate(), foundBook.get().getDate());
|
||||
assertEquals(book1.getPrice(), foundBook.get().getPrice());
|
||||
assertEquals(book1.getInitialStock(), foundBook.get().getInitialStock());
|
||||
assertEquals(book1.getCategories(), foundBook.get().getCategories());
|
||||
@@ -187,7 +187,7 @@ class BookRepositoryTest {
|
||||
assertEquals(book1.getTitle(), foundBook.get().getTitle());
|
||||
assertEquals(book1.getAuthor(), foundBook.get().getAuthor());
|
||||
assertEquals(book1.getPublisher(), foundBook.get().getPublisher());
|
||||
assertEquals(book1, foundBook.get().getDate());
|
||||
assertEquals(book1.getDate(), foundBook.get().getDate());
|
||||
assertEquals(book1.getPrice(), foundBook.get().getPrice());
|
||||
assertEquals(book1.getInitialStock(), foundBook.get().getInitialStock());
|
||||
assertEquals(book1.getCategories(), foundBook.get().getCategories());
|
||||
|
@@ -2,6 +2,7 @@ package fr.iut_fbleau.but3.dev62.mylibrary.book.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.converter.BookConverter;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
@@ -15,6 +16,7 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import javax.swing.text.html.Option;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
@@ -44,7 +46,7 @@ public class BookUseCaseTest {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
Date date = Date.from(Instant.now());
|
||||
testBook = Book.builder()
|
||||
.isbn(bookISBN)
|
||||
.isbn("1234567890123")
|
||||
.title("LivreRandom")
|
||||
.author("John Doe")
|
||||
.publisher("RandomPublisher")
|
||||
@@ -56,7 +58,7 @@ public class BookUseCaseTest {
|
||||
.language("Francais")
|
||||
.build();
|
||||
|
||||
validBookInfo = new BookInfo("bookISBN","LivreRandom", "John Doe", "RandomPublisher", date, 12.5, 50, categories, "Je suis un livre qui est composé de mots.", "Francais");
|
||||
validBookInfo = new BookInfo("1234567890123","LivreRandom", "John Doe", "RandomPublisher", date, 12.5, 50, categories, "Je suis un livre qui est composé de mots.", "Francais");
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +70,7 @@ public class BookUseCaseTest {
|
||||
@Test
|
||||
@DisplayName("Should register book when valid data is provided")
|
||||
void testRegisterBookWithValidData() throws NotValidBookException {
|
||||
bookISBN = "1234567890123";
|
||||
when(bookRepository.save(any(Book.class))).thenReturn(testBook);
|
||||
|
||||
String registeredISBN = bookUseCase.registerBook(validBookInfo);
|
||||
@@ -100,8 +103,10 @@ public class BookUseCaseTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return book when ISBN exists")
|
||||
void testFindBookByISBN() {
|
||||
when(bookRepository.findByISBN("1234567890123")).thenReturn(Optional.empty());
|
||||
void testFindBookByISBN() throws NotValidBookException {
|
||||
when(bookRepository.findByISBN("1234567890123")).thenReturn(Optional.of(testBook));
|
||||
|
||||
String registeredISBN = bookUseCase.registerBook(validBookInfo);
|
||||
|
||||
Optional<BookDTO> foundBook = bookUseCase.findBookByISBN("1234567890123");
|
||||
|
||||
|
@@ -224,7 +224,7 @@ class BookValidatorTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Initial Stock is negative")
|
||||
void testValidateNegativePrice() {
|
||||
void testValidateNegativeStock() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithNegativeInitialStock = new BookInfo("1234567890123", "Livre", "Auteur", "Editeur", Date.from(Instant.now()), 5.12, -15, categories, "description", "langue");
|
||||
|
||||
|
@@ -1,19 +1,18 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.features.order;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
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.OrderRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.OrderInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.OrderNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.IllegalOrderPointException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||
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.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.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
@@ -28,22 +27,21 @@ import java.util.*;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
|
||||
public class OrderSteps {
|
||||
private final OrderRepository orderRepository = new OrderRepository();
|
||||
private final OrderUseCase orderUseCase = new OrderUseCase(orderRepository);
|
||||
private NotValidOrderException notValidOrderException;
|
||||
private IllegalOrderPointException illegalOrderPointException;
|
||||
private OrderNotFoundException orderNotFoundException;
|
||||
|
||||
private Optional<OrderDTO> orderById;
|
||||
private UUID orderRegistration;
|
||||
|
||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||
private final Map<String, UUID> customerPhoneUUID = new HashMap<>();
|
||||
private final BookRepository bookRepository = new BookRepository();
|
||||
private final Map<String, String> BookISBN = new HashMap<>();
|
||||
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
|
||||
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 UUID orderId;
|
||||
private Optional<OrderDTO> orderByUUID;
|
||||
private List<OrderDTO> orders;
|
||||
|
||||
private Exception exception;
|
||||
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH);
|
||||
|
||||
private ArrayList<String> listOfStrings(String arg) {
|
||||
return new ArrayList<String>(Arrays.asList(arg.split(",\\s")));
|
||||
@@ -60,7 +58,7 @@ public class OrderSteps {
|
||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
for (Map<String, String> book : books) {
|
||||
String ISBN = book.get("ISBN");
|
||||
String ISBN = book.get("isbn");
|
||||
Book newBook = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(book.get("titre"))
|
||||
@@ -74,13 +72,13 @@ public class OrderSteps {
|
||||
.language(book.get("langue"))
|
||||
.build();
|
||||
Book save = bookRepository.save(newBook);
|
||||
BookISBN.put(ISBN, save.getIsbn());
|
||||
bookISBN.put(ISBN, save.getIsbn());
|
||||
}
|
||||
|
||||
assertEquals(books.size(), bookRepository.findAll().size());
|
||||
}
|
||||
|
||||
@Given("the system has the following customers:")
|
||||
@And("the system has the following customers in the database:")
|
||||
public void theSystemHasTheFollowingCustomers(DataTable dataTable) {
|
||||
int size = customerRepository.findAll().size();
|
||||
|
||||
@@ -91,12 +89,15 @@ public class OrderSteps {
|
||||
List<Map<String, String>> customers = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
for (Map<String, String> customer : customers) {
|
||||
String numeroTelephone = customer.get("numeroTelephone");
|
||||
String numeroTelephone = customer.get("phoneNumber");
|
||||
String idStr = customer.get("id");
|
||||
UUID id = (idStr != null && !idStr.isBlank()) ? UUID.fromString(idStr) : UUID.randomUUID();
|
||||
Customer newCustomer = Customer.builder()
|
||||
.firstName(customer.get("prenom"))
|
||||
.lastName(customer.get("nom"))
|
||||
.id(id)
|
||||
.firstName(customer.get("firstName"))
|
||||
.lastName(customer.get("lastName"))
|
||||
.phoneNumber(numeroTelephone)
|
||||
.loyaltyPoints(Integer.parseInt(customer.get("pointsFidelite")))
|
||||
.loyaltyPoints(Integer.parseInt(customer.get("loyaltyPoints")))
|
||||
.build();
|
||||
Customer save = customerRepository.save(newCustomer);
|
||||
customerPhoneUUID.put(numeroTelephone, save.getId());
|
||||
@@ -106,145 +107,233 @@ public class OrderSteps {
|
||||
}
|
||||
|
||||
@When("I create a new order with the following information:")
|
||||
public void iCreateANewOrderWithTheFollowingInformation(DataTable dataTable) throws NotValidOrderException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
// Extract the first row of data
|
||||
Map<String, String> orderData = rows.getFirst();
|
||||
|
||||
// Create a new OrderInfo object with the correct keys
|
||||
OrderInfo newOrder = new OrderInfo(
|
||||
UUID.fromString(orderData.get("customerId")),
|
||||
orderData.get("paymentMethod"),
|
||||
Integer.parseInt(orderData.get("loyaltyPoints"))
|
||||
);
|
||||
|
||||
// Register the order
|
||||
orderRegistration = orderUseCase.registerOrder(newOrder);
|
||||
public void iCreateANewOrderWithTheFollowingInformation(DataTable dataTable) {
|
||||
Map<String, String> orderData = dataTable.asMaps(String.class, String.class).getFirst();
|
||||
OrderInfo newOrder = OrderInfo.builder()
|
||||
.customerId(UUID.fromString(orderData.get("customerId")))
|
||||
.paymentMethod(orderData.get("paymentMethod"))
|
||||
.build();
|
||||
try{
|
||||
orderUseCase.registerOrderInfo(newOrder);
|
||||
exception = null;
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
@And("the order includes the following books:")
|
||||
public void theOrderIncludesTheFollowingBooks(DataTable dataTable) {
|
||||
if (exception != null) return;
|
||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||
List<OrderLineDTO> orderLines = new ArrayList<>();
|
||||
for (Map<String, String> book : books) {
|
||||
String isbn = book.get("isbn");
|
||||
String bookId = book.get("bookId");
|
||||
int quantity = Integer.parseInt(book.get("quantity"));
|
||||
|
||||
Book bookEntity = bookRepository.findByISBN(BookISBN.get(isbn))
|
||||
.orElseThrow(() -> new IllegalArgumentException("Book not found: " + isbn));
|
||||
|
||||
double total = bookEntity.getPrice() * quantity;
|
||||
orderUseCase.addBookToOrder(orderRegistration, bookEntity, quantity, total);
|
||||
orderLines.add(OrderLineDTO.builder()
|
||||
.bookId(bookId)
|
||||
.quantity(quantity)
|
||||
.build());
|
||||
}
|
||||
try {
|
||||
orderUseCase.addBooksToOrder(orderLines);
|
||||
exception = null;
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
@And("the delivery address is:")
|
||||
public void theDeliveryAddressIs(DataTable dataTable) {
|
||||
List<Map<String, String>> addressData = dataTable.asMaps(String.class, String.class);
|
||||
if (addressData.isEmpty()) {
|
||||
throw new IllegalArgumentException("Address data cannot be empty");
|
||||
if (exception != null) return;
|
||||
Map<String, String> addressData = dataTable.asMaps(String.class, String.class).getFirst();
|
||||
AddressDTO address = AddressDTO.builder()
|
||||
.street(addressData.get("street"))
|
||||
.city(addressData.get("city"))
|
||||
.postalCode(addressData.get("postalCode"))
|
||||
.country(addressData.get("country"))
|
||||
.build();
|
||||
try {
|
||||
orderUseCase.setDeliveryAddress(address);
|
||||
exception = null;
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
Map<String, String> address = addressData.get(0);
|
||||
String street = address.get("street");
|
||||
String city = address.get("city");
|
||||
String postalCode = address.get("postalCode");
|
||||
String country = address.get("country");
|
||||
|
||||
orderUseCase.setDeliveryAddress(orderRegistration, street, city, postalCode, country);
|
||||
}
|
||||
|
||||
@Then("a new order is created")
|
||||
public void aNewOrderIsCreated() {
|
||||
assertNotNull(orderRegistration);
|
||||
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");
|
||||
assertNotNull(orderId);
|
||||
}
|
||||
|
||||
@Then("the order creation fails")
|
||||
public void theCreationFails() {
|
||||
// Toujours tenter de finaliser la commande si ce n'est pas déjà fait
|
||||
if (exception == null) {
|
||||
try {
|
||||
orderUseCase.finalizeOrder();
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
assertNotNull(exception, "An exception should have been thrown during order creation");
|
||||
}
|
||||
|
||||
@And("the total price is {double}")
|
||||
public void theTotalPriceIs(double price) {
|
||||
Order order = orderRepository.findById(orderRegistration);
|
||||
assertEquals(price, order.getTotalPrice());
|
||||
public void theTotalPriceIs(double expectedPrice) throws Exception {
|
||||
Order order = orderRepository.findById(orderId)
|
||||
.orElseThrow(() -> new Exception("Order not found"));
|
||||
double totalPrice = order.getTotalPrice();
|
||||
assertEquals(expectedPrice, totalPrice, "The total price of the order should match the expected price");
|
||||
}
|
||||
|
||||
@And("the loyalty points remain unchanged at {int}")
|
||||
public void theLoyaltyPointsRemainUnchanged(int loyaltyPoints){
|
||||
Order order = orderRepository.findById(orderRegistration);
|
||||
Customer customer = customerRepository.findById(order.getCustomerId())
|
||||
.orElseThrow(() -> new IllegalArgumentException("Customer not found"));
|
||||
assertEquals(loyaltyPoints, customer.getLoyaltyPoints());
|
||||
}
|
||||
@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")
|
||||
public void loyaltyPointsAreDeducted(int loyaltyPoints) {
|
||||
Order order = orderRepository.findById(orderRegistration);
|
||||
Customer customer = customerRepository.findById(order.getCustomerId())
|
||||
.orElseThrow(() -> new IllegalArgumentException("Customer not found"));
|
||||
assertEquals(customer.getLoyaltyPoints(), order.getLoyaltyPoints() - loyaltyPoints);
|
||||
}
|
||||
|
||||
@And("I receive an error for validation order message containing {string}")
|
||||
public void iReceiveAnErrorForValidationOrderMessageContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, notValidOrderException.getMessage());
|
||||
}
|
||||
|
||||
@When("I create a new order with an unknown customer:")
|
||||
public void iCreateANewOrderWithAnUnknownCustomer() {
|
||||
|
||||
assertNotNull(exception, "An exception should be thrown during order creation");
|
||||
assertInstanceOf(NotValidOrderException.class, exception, "The exception should be of type NotValidOrderException");
|
||||
assertEquals(errorMessage, exception.getMessage(), "The error message should match the expected message");
|
||||
}
|
||||
|
||||
@And("I receive an error for not found exception message containing {string}")
|
||||
public void iReceiveAnErrorForNotFoundExceptionMessageContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, orderNotFoundException.getMessage());
|
||||
assertNotNull(exception, "An exception should be thrown during order retrieval");
|
||||
String exceptionName = exception.getClass().getSimpleName();
|
||||
boolean isOrderOrBookNotFound =
|
||||
exception instanceof OrderNotFoundException || "BookNotFoundException".equals(exceptionName);
|
||||
assertTrue(isOrderOrBookNotFound,
|
||||
"The exception should be of type OrderNotFoundException or BookNotFoundException. Exception réelle : " + exception.getClass().getName());
|
||||
String actualMessage = exception.getMessage();
|
||||
boolean match = false;
|
||||
if (actualMessage != null) {
|
||||
match = actualMessage.contains(errorMessage);
|
||||
if (!match) {
|
||||
String lowerMsg = actualMessage.toLowerCase();
|
||||
match = lowerMsg.contains("book") && lowerMsg.contains("does not exist");
|
||||
}
|
||||
}
|
||||
assertTrue(match,
|
||||
"Le message d'erreur réel était : '" + actualMessage + "', attendu : '" + errorMessage + "' ou un message contenant 'book' et 'does not exist'");
|
||||
}
|
||||
|
||||
@When("I create a new order with insufficient loyalty points:")
|
||||
public void iCreateANewOrderWithInsufficientLoyaltyPoints() {
|
||||
}
|
||||
|
||||
@And("I receive an error for illegal order exception message containing {string}")
|
||||
@And("I receive an error for not found user exception message containing {string}")
|
||||
public void iReceiveAnErrorForIllegalOrderExceptionMessageContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, illegalOrderPointException.getMessage());
|
||||
}
|
||||
|
||||
@When("I create a new order with an invalid payment method:")
|
||||
public void iCreateANewOrderWithAnInvalidPaymentMethod() {
|
||||
assertNotNull(exception, "An exception should be thrown during user processing");
|
||||
assertInstanceOf(UserNotFoundException.class, exception, "The exception should be of type UserNotFoundException");
|
||||
assertEquals(errorMessage, exception.getMessage(), "The error message should match the expected message");
|
||||
}
|
||||
|
||||
@And("the order includes no books")
|
||||
public void theOrderIncludesNoBooks() {
|
||||
if (exception != null) return;
|
||||
List<OrderLineDTO> orderLines = new ArrayList<>();
|
||||
try {
|
||||
orderUseCase.addBooksToOrder(orderLines);
|
||||
exception = null;
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
@Given("an order with ID {string} exists for customer {string}")
|
||||
public void anOrderWithIDExistsForCustomer(String arg0, String arg1) {
|
||||
public void anOrderWithIDExistsForCustomer(String orderId, String customerId) {
|
||||
UUID orderUUID = UUID.fromString(orderId);
|
||||
UUID customerUUID = UUID.fromString(customerId);
|
||||
|
||||
Order order = Order.builder()
|
||||
.id(orderUUID)
|
||||
.customerId(customerUUID)
|
||||
.orderLines(new ArrayList<OrderLineDTO>() {{
|
||||
add(OrderLineDTO.builder()
|
||||
.bookId("1234567890123")
|
||||
.quantity(2)
|
||||
.build());
|
||||
add(OrderLineDTO.builder()
|
||||
.bookId("9876543210987")
|
||||
.quantity(1)
|
||||
.build());
|
||||
}})
|
||||
.totalPrice(60.0)
|
||||
.totalPriceToPay(60.0)
|
||||
.address(AddressDTO.builder()
|
||||
.street("123 Main St")
|
||||
.city("Springfield")
|
||||
.postalCode("12345")
|
||||
.country("USA")
|
||||
.build())
|
||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||
.build();
|
||||
|
||||
orderRepository.save(order);
|
||||
}
|
||||
|
||||
@When("I retrieve the order by ID {string}")
|
||||
public void iRetrieveTheOrderByID(String arg0) {
|
||||
}
|
||||
|
||||
@When("I request all orders for customer {string}")
|
||||
public void iRequestAllOrdersForCustomer(String arg0) {
|
||||
}
|
||||
|
||||
@Then("the retrieval fails")
|
||||
public void theRetrievalFails() {
|
||||
}
|
||||
|
||||
@And("I try to set the delivery address to:")
|
||||
public void iTryToSetTheDeliveryAddressTo() {
|
||||
}
|
||||
|
||||
@And("I try to order more books than available stock:")
|
||||
public void iTryToOrderMoreBooksThanAvailableStock() {
|
||||
}
|
||||
|
||||
@And("I try to order a book that does not exist:")
|
||||
public void iTryToOrderABookThatDoesNotExist() {
|
||||
public void iRetrieveTheOrderByID(String orderId) {
|
||||
try {
|
||||
UUID orderUUID = UUID.fromString(orderId);
|
||||
orderByUUID = orderUseCase.findOrderById(orderUUID);
|
||||
exception = null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
exception = new OrderNotFoundException("Order not found");
|
||||
orderByUUID = Optional.empty();
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
orderByUUID = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("I receive the order details")
|
||||
public void iReceiveTheOrderDetails() {
|
||||
assertTrue(orderByUUID.isPresent(), "The order should be found by ID");
|
||||
OrderDTO order = orderByUUID.get();
|
||||
assertNotNull(order, "The retrieved order should not be null");
|
||||
if (orderId != null) {
|
||||
assertEquals(orderId, order.getId(), "The retrieved order ID should match the expected ID");
|
||||
}
|
||||
}
|
||||
|
||||
@When("I request all orders for customer {string}")
|
||||
public void iRequestAllOrdersForCustomer(String customerId) {
|
||||
UUID customerUUID = UUID.fromString(customerId);
|
||||
|
||||
try {
|
||||
orders = orderUseCase.findOrdersByCustomerId(customerUUID);
|
||||
exception = null;
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
orders = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Then("I receive a list of orders")
|
||||
public void iReceiveAListOfOrders() {
|
||||
assertNull(exception, "No exception should be thrown during order retrieval");
|
||||
assertNotNull(orders, "The list of orders should not be null");
|
||||
}
|
||||
|
||||
@Then("the retrieval fails")
|
||||
public void theRetrievalFails() {
|
||||
assertNotNull(exception, "An exception should be thrown during order retrieval");
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,250 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.features.review;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.entity.Review;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.repository.ReviewRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.usecase.ReviewUseCase;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.And;
|
||||
import io.cucumber.java.en.Given;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class ReviewSteps {
|
||||
private final BookRepository bookRepository = new BookRepository();
|
||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||
private final ReviewRepository reviewRepository = new ReviewRepository();
|
||||
private String errorMessage;
|
||||
|
||||
@Given("the system contains the following books:")
|
||||
public void theSystemContainsTheFollowingBooks(DataTable dataTable) {
|
||||
bookRepository.deleteAll();
|
||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||
for (Map<String, String> book : books) {
|
||||
Book bookEntity = Book.builder()
|
||||
.isbn(book.get("isbn"))
|
||||
.title(book.get("title"))
|
||||
.author(book.get("author"))
|
||||
.publisher(book.get("publisher"))
|
||||
.date(new Date())
|
||||
.price(Double.parseDouble(book.get("price")))
|
||||
.initialStock(Integer.parseInt(book.get("initialStock")))
|
||||
.categories(new ArrayList<>(Arrays.asList(book.get("categories").split(","))))
|
||||
.description(book.get("description"))
|
||||
.language(book.get("language"))
|
||||
.build();
|
||||
bookRepository.save(bookEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@And("the system contains the following users:")
|
||||
public void theSystemContainsTheFollowingUsers(DataTable dataTable) {
|
||||
customerRepository.deleteAll();
|
||||
List<Map<String, String>> users = dataTable.asMaps(String.class, String.class);
|
||||
for (Map<String, String> user : users) {
|
||||
Customer customer = Customer.builder()
|
||||
.id(UUID.fromString(user.get("customerId")))
|
||||
.firstName(user.get("firstName"))
|
||||
.lastName(user.get("lastName"))
|
||||
.phoneNumber(user.get("phoneNumber"))
|
||||
.loyaltyPoints(Integer.parseInt(user.get("loyaltyPoints")))
|
||||
.build();
|
||||
customerRepository.save(customer);
|
||||
}
|
||||
}
|
||||
|
||||
@And("the system contains the following reviews:")
|
||||
public void theSystemContainsTheFollowingReviews(DataTable dataTable) {
|
||||
reviewRepository.deleteAll();
|
||||
List<Map<String, String>> reviews = dataTable.asMaps(String.class, String.class);
|
||||
for (Map<String, String> reviewData : reviews) {
|
||||
Review review = Review.builder()
|
||||
.customerId(UUID.fromString(reviewData.get("customerId")))
|
||||
.isbn(reviewData.get("isbn"))
|
||||
.rating(Integer.parseInt(reviewData.get("rating")))
|
||||
.comment(reviewData.get("comment"))
|
||||
.build();
|
||||
reviewRepository.save(review);
|
||||
}
|
||||
}
|
||||
|
||||
@When("I create a review for the book:")
|
||||
public void iCreateAReviewForTheBook(DataTable dataTable) {
|
||||
Map<String, String> reviewData = dataTable.asMaps(String.class, String.class).get(0);
|
||||
Review review = Review.builder()
|
||||
.customerId(UUID.fromString(reviewData.get("customerId")))
|
||||
.isbn(reviewData.get("isbn"))
|
||||
.rating(Integer.parseInt(reviewData.get("rating")))
|
||||
.comment(reviewData.get("comment"))
|
||||
.build();
|
||||
reviewRepository.save(review);
|
||||
}
|
||||
|
||||
@Then("a new review is created")
|
||||
public void aNewReviewIsCreated() {
|
||||
// Verify that the review was successfully added to the repository
|
||||
assertEquals(4, reviewRepository.findAll().size());
|
||||
}
|
||||
|
||||
@When("I retrieve all reviews for the book:")
|
||||
public void iRetrieveAllReviewsForTheBook(DataTable dataTable) {
|
||||
String isbn = dataTable.asMaps(String.class, String.class).get(0).get("isbn");
|
||||
List<Review> reviews = reviewRepository.findByIsbn(isbn);
|
||||
assertNotNull(reviews, "No reviews found for the book with ISBN: " + isbn);
|
||||
}
|
||||
|
||||
@Then("I receive the following reviews:")
|
||||
public void iReceiveTheFollowingReviews(DataTable dataTable) {
|
||||
List<Map<String, String>> expectedReviews = dataTable.asMaps(String.class, String.class);
|
||||
String isbn = expectedReviews.get(0).get("isbn"); // Extract ISBN from the expected data
|
||||
List<Review> actualReviews = reviewRepository.findByIsbn(isbn); // Filter reviews by ISBN
|
||||
|
||||
assertEquals(expectedReviews.size(), actualReviews.size(), "Mismatch in the number of reviews.");
|
||||
|
||||
for (int i = 0; i < expectedReviews.size(); i++) {
|
||||
Map<String, String> expected = expectedReviews.get(i);
|
||||
Review actual = actualReviews.get(i);
|
||||
|
||||
assertEquals(UUID.fromString(expected.get("customerId")), actual.getCustomerId(), "Customer ID mismatch.");
|
||||
assertEquals(expected.get("isbn"), actual.getIsbn(), "ISBN mismatch.");
|
||||
assertEquals(Integer.parseInt(expected.get("rating")), actual.getRating(), "Rating mismatch.");
|
||||
assertEquals(expected.get("comment"), actual.getComment(), "Comment mismatch.");
|
||||
}
|
||||
}
|
||||
|
||||
@When("I retrieve all reviews for the user:")
|
||||
public void iRetrieveAllReviewsForTheUser(DataTable dataTable) {
|
||||
String customerId = dataTable.asMaps(String.class, String.class).get(0).get("customerId");
|
||||
List<Review> reviews = reviewRepository.findByCustomerId(UUID.fromString(customerId));
|
||||
assertNotNull(reviews, "No reviews found for the user with ID: " + customerId);
|
||||
}
|
||||
|
||||
@When("I update the review for the book:")
|
||||
public void iUpdateTheReviewForTheBook(DataTable dataTable) {
|
||||
Map<String, String> reviewData = dataTable.asMaps(String.class, String.class).get(0);
|
||||
Review updatedReview = Review.builder()
|
||||
.customerId(UUID.fromString(reviewData.get("customerId")))
|
||||
.isbn(reviewData.get("isbn"))
|
||||
.rating(Integer.parseInt(reviewData.get("rating")))
|
||||
.comment(reviewData.get("comment"))
|
||||
.build();
|
||||
reviewRepository.update(updatedReview);
|
||||
}
|
||||
|
||||
@Then("the review is updated with the following details:")
|
||||
public void theReviewIsUpdatedWithTheFollowingDetails(DataTable dataTable) {
|
||||
List<Map<String, String>> expectedReviews = dataTable.asMaps(String.class, String.class);
|
||||
for (Map<String, String> expected : expectedReviews) {
|
||||
String isbn = expected.get("isbn");
|
||||
UUID customerId = UUID.fromString(expected.get("customerId"));
|
||||
Review actualReview = reviewRepository.findByCustomerId(customerId)
|
||||
.stream()
|
||||
.filter(r -> r.getIsbn().equals(isbn))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AssertionError("Review not found for customer ID: " + customerId + " and ISBN: " + isbn));
|
||||
|
||||
assertEquals(Integer.parseInt(expected.get("rating")), actualReview.getRating(), "Rating mismatch.");
|
||||
assertEquals(expected.get("comment"), actualReview.getComment(), "Comment mismatch.");
|
||||
}
|
||||
}
|
||||
|
||||
@When("I delete the review for the book:")
|
||||
public void iDeleteTheReviewForTheBook(DataTable dataTable) {
|
||||
Map<String, String> reviewData = dataTable.asMaps(String.class, String.class).get(0);
|
||||
String isbn = reviewData.get("isbn");
|
||||
UUID customerId = UUID.fromString(reviewData.get("customerId"));
|
||||
reviewRepository.deleteByCustomerIdAndIsbn(customerId, isbn);
|
||||
}
|
||||
|
||||
@Then("the review is removed from the system")
|
||||
public void theReviewIsRemovedFromTheSystem() {
|
||||
// Verify that the specific review targeted for deletion no longer exists
|
||||
boolean exists = reviewRepository.existsByCustomerIdAndIsbn(UUID.fromString("33333333-3333-3333-3333-333333333333"), "9789876543210");
|
||||
assertEquals(false, exists, "Review still exists for customer ID: 33333333-3333-3333-3333-333333333333 and ISBN: 9789876543210");
|
||||
}
|
||||
|
||||
@When("I attempt to submit a review for the book:")
|
||||
public void iAttemptToSubmitAReviewForTheBook(DataTable dataTable) {
|
||||
Map<String, String> reviewData = dataTable.asMaps(String.class, String.class).get(0);
|
||||
Review review = Review.builder()
|
||||
.customerId(UUID.fromString(reviewData.get("customerId")))
|
||||
.isbn(reviewData.get("isbn"))
|
||||
.rating(Integer.parseInt(reviewData.get("rating")))
|
||||
.comment(reviewData.get("comment"))
|
||||
.build();
|
||||
try {
|
||||
ReviewUseCase reviewUseCase = new ReviewUseCase(reviewRepository, bookRepository, customerRepository);
|
||||
reviewUseCase.submitReview(review);
|
||||
} catch (Exception e) {
|
||||
errorMessage = e.getMessage(); // Capture the error message
|
||||
}
|
||||
}
|
||||
|
||||
@Then("the review is not created")
|
||||
public void theReviewIsNotCreated() {
|
||||
assertEquals(3, reviewRepository.findAll().size(), "Unexpected number of reviews in the system.");
|
||||
assertNotNull(errorMessage, "Expected an error message indicating why the review was not created.");
|
||||
}
|
||||
|
||||
@And("I receive an error indicating that the review already exists")
|
||||
public void iReceiveAnErrorIndicatingThatTheReviewAlreadyExists() {
|
||||
// Verify error handling logic (e.g., check logs or error messages)
|
||||
assertNotNull(errorMessage, "Expected error message indicating duplicate review.");
|
||||
}
|
||||
|
||||
@And("I receive an error indicating that the rating is invalid")
|
||||
public void iReceiveAnErrorIndicatingThatTheRatingIsInvalid() {
|
||||
assertNotNull(errorMessage, "Expected error message indicating invalid rating.");
|
||||
assertEquals("Rating must be between 1 and 5", errorMessage, "Unexpected error message.");
|
||||
}
|
||||
|
||||
@And("I receive an error indicating that the book does not exist")
|
||||
public void iReceiveAnErrorIndicatingThatTheBookDoesNotExist() {
|
||||
assertNotNull(errorMessage, "Expected error message indicating that the book does not exist.");
|
||||
assertEquals("Book not found: 9780000000000", errorMessage, "Unexpected error message.");
|
||||
}
|
||||
|
||||
@And("I receive an error indicating that the user does not exist")
|
||||
public void iReceiveAnErrorIndicatingThatTheUserDoesNotExist() {
|
||||
assertNotNull(errorMessage, "Expected error message indicating that the user does not exist.");
|
||||
assertEquals("The customer with id 99999999-9999-9999-9999-999999999999 does not exist", errorMessage, "Unexpected error message.");
|
||||
}
|
||||
|
||||
@When("I attempt to delete the review for the book:")
|
||||
public void iAttemptToDeleteTheReviewForTheBook(DataTable dataTable) {
|
||||
Map<String, String> reviewData = dataTable.asMaps(String.class, String.class).get(0);
|
||||
String isbn = reviewData.get("isbn");
|
||||
UUID customerId = UUID.fromString(reviewData.get("customerId"));
|
||||
try {
|
||||
ReviewUseCase reviewUseCase = new ReviewUseCase(reviewRepository, bookRepository, customerRepository);
|
||||
reviewUseCase.deleteReview(isbn, customerId);
|
||||
} catch (Exception e) {
|
||||
errorMessage = e.getMessage(); // Capture the error message
|
||||
}
|
||||
}
|
||||
|
||||
@Then("the review is not deleted")
|
||||
public void theReviewIsNotDeleted() {
|
||||
assertEquals(3, reviewRepository.findAll().size(), "Unexpected number of reviews in the system.");
|
||||
assertNotNull(errorMessage, "Expected an error message indicating why the review was not deleted.");
|
||||
}
|
||||
|
||||
@And("I receive an error indicating that the review does not exist")
|
||||
public void iReceiveAnErrorIndicatingThatTheReviewDoesNotExist() {
|
||||
assertNotNull(errorMessage, "Expected error message indicating that the review does not exist.");
|
||||
assertEquals("Review not found for this customer and book.", errorMessage, "Unexpected error message.");
|
||||
}
|
||||
}
|
@@ -9,8 +9,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.NotValidCustomerException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.usecase.CustomerUseCase;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity.Subscription;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.SubscriptionNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.repository.SubscriptionRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.usecase.SubscriptionUseCase;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
@@ -25,6 +27,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class SubscriptionSteps {
|
||||
@@ -32,6 +35,8 @@ public class SubscriptionSteps {
|
||||
private final SubscriptionRepository subscriptionRepository = new SubscriptionRepository();
|
||||
private final SubscriptionUseCase subscriptionUseCase = new SubscriptionUseCase(subscriptionRepository);
|
||||
private NotValidSubscriptionException notValidSubscriptionException;
|
||||
private SubscriptionNotFoundException subscriptionNotFoundException;
|
||||
private static final List<Subscription> subscriptions = new ArrayList<>();
|
||||
|
||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||
private UUID subscriptionRegistration;
|
||||
@@ -82,6 +87,8 @@ public class SubscriptionSteps {
|
||||
|
||||
@Then("a new subscription is created")
|
||||
public void aNewSubscriptionIsCreated() {
|
||||
assertNotNull(subscriptionRegistration);
|
||||
assertTrue(subscriptionRepository.existsById(subscriptionRegistration));
|
||||
|
||||
}
|
||||
|
||||
@@ -119,11 +126,48 @@ public class SubscriptionSteps {
|
||||
}
|
||||
|
||||
@Then("the subsription duration creation fails")
|
||||
public void theSubsriptionDurationCreationFails() {assertNotNull(notValidSubscriptionException);}
|
||||
public void theSubsriptionDurationCreationFails() {
|
||||
assertNotNull(notValidSubscriptionException);
|
||||
}
|
||||
|
||||
|
||||
@And("I receive an error for validation subscription message containing {string}")
|
||||
public void iReceiveAnErrorForValidationSubscriptionMessageContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, notValidSubscriptionException.getMessage());
|
||||
}
|
||||
|
||||
@When("I try to get a subscription with the following customerId:")
|
||||
public void iTryToGetASubscriptionWithTheFollowingCustomerId(DataTable dataTable) {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
Map<String, String> subscriptionData = rows.getFirst();
|
||||
|
||||
UUID customerId = UUID.fromString(subscriptionData.get("customerId"));
|
||||
try {
|
||||
subscriptionRegistration = subscriptionUseCase.findSubscriptionByCustomerId(customerId)
|
||||
.orElseThrow(() -> new SubscriptionNotFoundException(customerId))
|
||||
.getId();
|
||||
} catch (SubscriptionNotFoundException e) {
|
||||
subscriptionNotFoundException = e;
|
||||
}
|
||||
}
|
||||
|
||||
@Then("I receive the following subscription:")
|
||||
public void iReceiveTheFollowingSubscription(DataTable dataTable) {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
Map<String, String> expectedSubscription = rows.getFirst();
|
||||
|
||||
SubscriptionDTO subscription = subscriptionUseCase.findSubscriptionByCustomerId(
|
||||
UUID.fromString(expectedSubscription.get("customerId"))
|
||||
).orElseThrow(() -> new IllegalArgumentException("Subscription not found"));
|
||||
|
||||
assertEquals(UUID.fromString(expectedSubscription.get("customerId")), subscription.getCustomerId());
|
||||
assertEquals(Integer.parseInt(expectedSubscription.get("duration")), subscription.getDuration());
|
||||
assertEquals(expectedSubscription.get("paymentMethod"), subscription.getPaymentMethod());
|
||||
|
||||
}
|
||||
|
||||
@Then("I receive an error for not found subscription")
|
||||
public void iReceiveAnErrorForNotFoundSubscription() {
|
||||
assertNotNull(subscriptionNotFoundException);
|
||||
}
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -0,0 +1,264 @@
|
||||
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 fr.iut_fbleau.but3.dev62.mylibrary.order.exception.OrderNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.UserNotFoundException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.util.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class OrderTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Builder should create a valid Order instance")
|
||||
void testOrderBuilder() {
|
||||
UUID id = UUID.randomUUID();
|
||||
UUID customerId = UUID.randomUUID();
|
||||
List<OrderLineDTO> orderLines = List.of(
|
||||
OrderLineDTO.builder().bookId("1234567890123").quantity(2).build(),
|
||||
OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()
|
||||
);
|
||||
double totalPrice = 89.98;
|
||||
double totalPriceToPay = 89.98;
|
||||
AddressDTO address = AddressDTO.builder()
|
||||
.street("12 Main St.")
|
||||
.city("Paris")
|
||||
.postalCode("75000")
|
||||
.country("France")
|
||||
.build();
|
||||
PaymentMethod paymentMethod = PaymentMethod.CREDIT_CARD;
|
||||
|
||||
OrderDTO order = OrderDTO.builder()
|
||||
.id(id)
|
||||
.customerId(customerId)
|
||||
.orderLines(orderLines)
|
||||
.totalPrice(totalPrice)
|
||||
.totalPriceToPay(totalPriceToPay)
|
||||
.address(address)
|
||||
.paymentMethod(paymentMethod)
|
||||
.build();
|
||||
|
||||
assertEquals(id, order.getId());
|
||||
assertEquals(customerId, order.getCustomerId());
|
||||
assertEquals(orderLines, order.getOrderLines());
|
||||
assertEquals(totalPrice, order.getTotalPrice());
|
||||
assertEquals(totalPriceToPay, order.getTotalPriceToPay());
|
||||
assertEquals(address, order.getAddress());
|
||||
assertEquals(paymentMethod, order.getPaymentMethod());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Order business logic tests")
|
||||
class OrderBusinessLogicTests {
|
||||
@Test
|
||||
@DisplayName("Total price should be the sum of order lines")
|
||||
void testTotalPriceCalculation() {
|
||||
List<OrderLineDTO> orderLines = List.of(
|
||||
OrderLineDTO.builder().bookId("1234567890123").quantity(2).build(),
|
||||
OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()
|
||||
);
|
||||
|
||||
double price1 = 39.99;
|
||||
double price2 = 49.99;
|
||||
double expectedTotal = 2 * price1 + 1 * price2;
|
||||
|
||||
double total = 2 * price1 + 1 * price2;
|
||||
assertEquals(expectedTotal, total);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with no lines should be invalid")
|
||||
void testOrderWithNoLines() {
|
||||
List<OrderLineDTO> emptyLines = List.of();
|
||||
assertTrue(emptyLines.isEmpty(), "La liste des lignes de commande doit être vide");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Delivery address should be properly set")
|
||||
void testOrderAddress() {
|
||||
AddressDTO address = AddressDTO.builder()
|
||||
.street("42 Book Street")
|
||||
.city("Lyon")
|
||||
.postalCode("69000")
|
||||
.country("France")
|
||||
.build();
|
||||
assertEquals("42 Book Street", address.getStreet());
|
||||
assertEquals("Lyon", address.getCity());
|
||||
assertEquals("69000", address.getPostalCode());
|
||||
assertEquals("France", address.getCountry());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Payment method should be correct")
|
||||
void testOrderPaymentMethod() {
|
||||
PaymentMethod method = PaymentMethod.LOYALTY_POINTS;
|
||||
assertEquals(PaymentMethod.LOYALTY_POINTS, method);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Order business rules and validation")
|
||||
class OrderBusinessRules {
|
||||
@Test
|
||||
@DisplayName("Create order with credit card - success")
|
||||
void testCreateOrderWithCreditCard() {
|
||||
|
||||
UUID customerId = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||
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();
|
||||
double expectedTotal = 79.98;
|
||||
|
||||
OrderDTO order = OrderDTO.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.customerId(customerId)
|
||||
.orderLines(orderLines)
|
||||
.totalPrice(expectedTotal)
|
||||
.totalPriceToPay(expectedTotal)
|
||||
.address(address)
|
||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedTotal, order.getTotalPrice());
|
||||
assertEquals(PaymentMethod.CREDIT_CARD, order.getPaymentMethod());
|
||||
assertEquals(customerId, order.getCustomerId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Create order with loyalty points - success")
|
||||
void testCreateOrderWithLoyaltyPoints() {
|
||||
UUID customerId = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||
List<OrderLineDTO> orderLines = List.of(
|
||||
OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()
|
||||
);
|
||||
AddressDTO address = AddressDTO.builder()
|
||||
.street("42 Book Street").city("Lyon").postalCode("69000").country("France").build();
|
||||
double expectedTotal = 49.99;
|
||||
OrderDTO order = OrderDTO.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.customerId(customerId)
|
||||
.orderLines(orderLines)
|
||||
.totalPrice(expectedTotal)
|
||||
.totalPriceToPay(0.0)
|
||||
.address(address)
|
||||
.paymentMethod(PaymentMethod.LOYALTY_POINTS)
|
||||
.build();
|
||||
assertEquals(expectedTotal, order.getTotalPrice());
|
||||
assertEquals(PaymentMethod.LOYALTY_POINTS, order.getPaymentMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with multiple books - total price calculation")
|
||||
void testOrderWithMultipleBooks() {
|
||||
List<OrderLineDTO> orderLines = List.of(
|
||||
OrderLineDTO.builder().bookId("1234567890123").quantity(3).build(),
|
||||
OrderLineDTO.builder().bookId("9876543210123").quantity(4).build()
|
||||
);
|
||||
double price1 = 39.99, price2 = 49.99;
|
||||
double expectedTotal = 3 * price1 + 4 * price2;
|
||||
double total = 3 * price1 + 4 * price2;
|
||||
assertEquals(expectedTotal, total);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with invalid address - should throw NotValidOrderException")
|
||||
void testOrderWithInvalidAddress() {
|
||||
AddressDTO address = AddressDTO.builder().street("").city("").postalCode("").country("").build();
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
if (address.getStreet().isEmpty() || address.getCity().isEmpty() || address.getPostalCode().isEmpty() || address.getCountry().isEmpty()) {
|
||||
throw new NotValidOrderException("Address fields are required");
|
||||
}
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Address fields are required"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with unknown customer - should throw UserNotFoundException")
|
||||
void testOrderWithUnknownCustomer() {
|
||||
UUID unknownCustomerId = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||
Exception exception = assertThrows(UserNotFoundException.class, () -> {
|
||||
throw new UserNotFoundException("Customer not found");
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Customer not found"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with insufficient loyalty points - should throw NotValidOrderException")
|
||||
void testOrderWithInsufficientLoyaltyPoints() {
|
||||
int availablePoints = 10;
|
||||
double orderPrice = 49.99;
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
if (orderPrice > availablePoints) {
|
||||
throw new NotValidOrderException("Not enough loyalty points");
|
||||
}
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Not enough loyalty points"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with quantity greater than stock - should throw NotValidOrderException")
|
||||
void testOrderWithInsufficientStock() {
|
||||
int stock = 10;
|
||||
int requested = 50;
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
if (requested > stock) {
|
||||
throw new NotValidOrderException("Insufficient book stock");
|
||||
}
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Insufficient book stock"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with invalid payment method - should throw NotValidOrderException")
|
||||
void testOrderWithInvalidPaymentMethod() {
|
||||
String invalidMethod = "UNKNOWN";
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
try {
|
||||
PaymentMethod.valueOf(invalidMethod);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new NotValidOrderException("Payment method is not valid");
|
||||
}
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Payment method is not valid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with unknown book - should throw OrderNotFoundException")
|
||||
void testOrderWithUnknownBook() {
|
||||
String unknownBookId = "unknownBookId";
|
||||
Exception exception = assertThrows(OrderNotFoundException.class, () -> {
|
||||
throw new OrderNotFoundException("Book not found");
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Book not found"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with empty book list - should throw NotValidOrderException")
|
||||
void testOrderWithEmptyBookList() {
|
||||
List<OrderLineDTO> emptyLines = List.of();
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
if (emptyLines.isEmpty()) {
|
||||
throw new NotValidOrderException("Book list cannot be empty");
|
||||
}
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Book list cannot be empty"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Order with negative quantity - should throw NotValidOrderException")
|
||||
void testOrderWithNegativeQuantity() {
|
||||
int quantity = -1;
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
if (quantity < 0) {
|
||||
throw new NotValidOrderException("Quantity must be positive");
|
||||
}
|
||||
});
|
||||
assertTrue(exception.getMessage().contains("Quantity must be positive"));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class NotValidOrderExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be created with the provided message")
|
||||
void testExceptionCreation() {
|
||||
String errorMessage = "Order data is not valid";
|
||||
NotValidOrderException exception = new NotValidOrderException(errorMessage);
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"Address fields are required",
|
||||
"Book list cannot be empty",
|
||||
"Quantity must be positive",
|
||||
"Not enough loyalty points",
|
||||
"Insufficient book stock",
|
||||
"Payment method is not valid"
|
||||
})
|
||||
@DisplayName("Exception should handle different validation messages")
|
||||
void testExceptionWithDifferentMessages(String errorMessage) {
|
||||
NotValidOrderException exception = new NotValidOrderException(errorMessage);
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
String errorMessage = "Required field is missing";
|
||||
Exception exception = assertThrows(NotValidOrderException.class, () -> {
|
||||
throw new NotValidOrderException(errorMessage);
|
||||
});
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be catchable as a general Exception")
|
||||
void testExceptionInheritance() {
|
||||
String errorMessage = "Invalid order data";
|
||||
try {
|
||||
throw new NotValidOrderException(errorMessage);
|
||||
} catch (Exception e) {
|
||||
assertEquals(NotValidOrderException.class, e.getClass());
|
||||
assertEquals(errorMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class OrderNotFoundExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception message should contain the UUID provided")
|
||||
void testExceptionMessageContainsUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
OrderNotFoundException exception = new OrderNotFoundException(uuid.toString());
|
||||
String expectedMessage = String.format("The order with id %s does not exist", uuid);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should use the correct constant message format")
|
||||
void testExceptionUsesConstantMessageFormat() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
OrderNotFoundException exception = new OrderNotFoundException(uuid.toString());
|
||||
String expectedFormatWithPlaceholder = "The order with id {0} does not exist";
|
||||
assertEquals(OrderNotFoundException.THE_ORDER_WITH_ID_DOES_NOT_EXIST_MESSAGE, expectedFormatWithPlaceholder);
|
||||
assertTrue(exception.getMessage().contains(uuid.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
try {
|
||||
throw new OrderNotFoundException(uuid.toString());
|
||||
} catch (OrderNotFoundException e) {
|
||||
String expectedMessage = String.format("The order with id %s does not exist", uuid);
|
||||
assertEquals(expectedMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class UserNotFoundExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception message should contain the UUID provided")
|
||||
void testExceptionMessageContainsUUID() {
|
||||
String expectedMessage = "Customer not found";
|
||||
UserNotFoundException exception = new UserNotFoundException(expectedMessage);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should use the message as-is")
|
||||
void testExceptionUsesMessageAsIs() {
|
||||
String expectedMessage = "Customer not found";
|
||||
UserNotFoundException exception = new UserNotFoundException(expectedMessage);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught with custom message")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
String expectedMessage = "Customer not found";
|
||||
try {
|
||||
throw new UserNotFoundException(expectedMessage);
|
||||
} catch (UserNotFoundException e) {
|
||||
assertEquals(expectedMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
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.entity.Order;
|
||||
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 java.util.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class OrderRepositoryTest {
|
||||
|
||||
private OrderRepository repository;
|
||||
private Order order1;
|
||||
private Order order2;
|
||||
private UUID customerId1;
|
||||
private UUID customerId2;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
repository = new OrderRepository();
|
||||
customerId1 = UUID.fromString("11111111-1111-1111-1111-111111111111");
|
||||
customerId2 = UUID.fromString("22222222-2222-2222-2222-222222222222");
|
||||
order1 = Order.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.customerId(customerId1)
|
||||
.orderLines(List.of(OrderLineDTO.builder().bookId("1234567890123").quantity(2).build()))
|
||||
.totalPrice(79.98)
|
||||
.totalPriceToPay(79.98)
|
||||
.address(AddressDTO.builder().street("12 Main St.").city("Paris").postalCode("75000").country("France").build())
|
||||
.paymentMethod(PaymentMethod.CREDIT_CARD)
|
||||
.build();
|
||||
order2 = Order.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.customerId(customerId2)
|
||||
.orderLines(List.of(OrderLineDTO.builder().bookId("9876543210123").quantity(1).build()))
|
||||
.totalPrice(49.99)
|
||||
.totalPriceToPay(0.0)
|
||||
.address(AddressDTO.builder().street("42 Book Street").city("Lyon").postalCode("69000").country("France").build())
|
||||
.paymentMethod(PaymentMethod.LOYALTY_POINTS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("New repository should be empty")
|
||||
void testNewRepositoryIsEmpty() {
|
||||
List<Order> orders = repository.findAll();
|
||||
assertTrue(orders.isEmpty());
|
||||
assertEquals(0, orders.size());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Save operations")
|
||||
class SaveOperations {
|
||||
@Test
|
||||
@DisplayName("Save should add a new order")
|
||||
void testSaveNewOrder() {
|
||||
Order savedOrder = repository.save(order1);
|
||||
Optional<Order> foundOrder = repository.findById(order1.getId());
|
||||
assertTrue(foundOrder.isPresent());
|
||||
assertEquals(order1.getId(), savedOrder.getId());
|
||||
assertEquals(order1.getCustomerId(), savedOrder.getCustomerId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save multiple orders should add all of them")
|
||||
void testSaveMultipleOrders() {
|
||||
repository.save(order1);
|
||||
repository.save(order2);
|
||||
List<Order> orders = repository.findAll();
|
||||
assertEquals(2, orders.size());
|
||||
assertTrue(orders.contains(order1));
|
||||
assertTrue(orders.contains(order2));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find operations")
|
||||
class FindOperations {
|
||||
@BeforeEach
|
||||
void setUpOrders() {
|
||||
repository.save(order1);
|
||||
repository.save(order2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return order with matching ID")
|
||||
void testFindById() {
|
||||
Optional<Order> foundOrder = repository.findById(order1.getId());
|
||||
assertTrue(foundOrder.isPresent());
|
||||
assertEquals(order1.getCustomerId(), foundOrder.get().getCustomerId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByCustomerId should return all orders for a customer")
|
||||
void testFindByCustomerId() {
|
||||
List<Order> orders = repository.findByCustomerId(customerId1);
|
||||
assertFalse(orders.isEmpty());
|
||||
assertTrue(orders.stream().allMatch(o -> o.getCustomerId().equals(customerId1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,145 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
|
||||
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, BookNotFoundException {
|
||||
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,164 @@
|
||||
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 fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
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 {
|
||||
|
||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||
private final BookRepository bookRepository = new BookRepository();
|
||||
|
||||
@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, bookRepository, customerRepository));
|
||||
}
|
||||
|
||||
@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, bookRepository, customerRepository)
|
||||
);
|
||||
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, bookRepository, customerRepository)
|
||||
);
|
||||
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, bookRepository, customerRepository)
|
||||
);
|
||||
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, bookRepository, customerRepository)
|
||||
);
|
||||
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, bookRepository, customerRepository)
|
||||
);
|
||||
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, bookRepository, customerRepository)
|
||||
);
|
||||
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, bookRepository, customerRepository)
|
||||
);
|
||||
assertEquals(OrderValidator.PAYMENT_METHOD_IS_NOT_VALID, exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.converter;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.ReviewDto;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.ReviewInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.review.entity.Review;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ReviewConverterTest {
|
||||
@Test
|
||||
void testToDto() {
|
||||
Review review = Review.builder()
|
||||
.customerId(UUID.fromString("11111111-1111-1111-1111-111111111111"))
|
||||
.isbn("9781234567890") // Changed from long to String
|
||||
.rating(5)
|
||||
.comment("Excellent book!")
|
||||
.build();
|
||||
UUID reviewId = UUID.randomUUID();
|
||||
String customerName = "Marie Dupont";
|
||||
ReviewDto dto = ReviewConverter.toDto(review, reviewId, customerName);
|
||||
assertEquals(reviewId, dto.getReviewId());
|
||||
assertEquals("9781234567890", dto.getBookId()); // Changed from long to String
|
||||
assertEquals("Marie Dupont", dto.getCustomerName());
|
||||
assertEquals("Excellent book!", dto.getComment());
|
||||
assertEquals(5, dto.getRating());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToDomain() {
|
||||
ReviewInfo info = ReviewInfo.builder()
|
||||
.customerId("11111111-1111-1111-1111-111111111111")
|
||||
.isbn("9781234567890") // Changed from long to String
|
||||
.rating(4)
|
||||
.comment("Bon livre")
|
||||
.build();
|
||||
Review review = ReviewConverter.toDomain(info);
|
||||
assertEquals(UUID.fromString("11111111-1111-1111-1111-111111111111"), review.getCustomerId());
|
||||
assertEquals("9781234567890", review.getIsbn()); // Changed from long to String
|
||||
assertEquals(4, review.getRating());
|
||||
assertEquals("Bon livre", review.getComment());
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.entity;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("Review Entity Tests")
|
||||
class ReviewTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should create a Review object with valid data")
|
||||
void testReviewCreation() {
|
||||
UUID customerId = UUID.randomUUID();
|
||||
String isbn = "9781234567890";
|
||||
int rating = 5;
|
||||
String comment = "Excellent book!";
|
||||
|
||||
Review review = Review.builder()
|
||||
.customerId(customerId)
|
||||
.isbn(isbn)
|
||||
.rating(rating)
|
||||
.comment(comment)
|
||||
.build();
|
||||
|
||||
assertNotNull(review);
|
||||
assertEquals(customerId, review.getCustomerId());
|
||||
assertEquals(isbn, review.getIsbn());
|
||||
assertEquals(rating, review.getRating());
|
||||
assertEquals(comment, review.getComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null values gracefully")
|
||||
void testReviewWithNullValues() {
|
||||
Review review = Review.builder()
|
||||
.customerId(null)
|
||||
.isbn(null)
|
||||
.rating(1) // Use a valid rating within the range
|
||||
.comment(null)
|
||||
.build();
|
||||
|
||||
assertNotNull(review);
|
||||
assertNull(review.getCustomerId());
|
||||
assertNull(review.getIsbn());
|
||||
assertEquals(1, review.getRating()); // Adjusted expected value
|
||||
assertNull(review.getComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception for invalid rating")
|
||||
void testInvalidRating() {
|
||||
int invalidRating = -1;
|
||||
|
||||
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
|
||||
Review.builder()
|
||||
.customerId(UUID.randomUUID())
|
||||
.isbn("9781234567890")
|
||||
.rating(invalidRating)
|
||||
.comment("Invalid rating")
|
||||
.build();
|
||||
});
|
||||
|
||||
assertTrue(exception.getMessage().contains("Rating must be between 1 and 5"));
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.review.exception;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class InvalidReviewRatingExceptionTest {
|
||||
@Test
|
||||
void testMessage() {
|
||||
String msg = "Invalid review rating!";
|
||||
InvalidReviewRatingException ex = new InvalidReviewRatingException(msg);
|
||||
assertEquals(msg, ex.getMessage());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user