forked from pierront/mylibrary-template
reglage order
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
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 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.exception.CustomerNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.AdresseLivraison;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.LigneCommandeInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.ModePaiement;
|
||||
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.NotValidOrderException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.repository.OrderRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.usecase.OrderUseCase;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.Before;
|
||||
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.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OrderSteps {
|
||||
|
||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||
private final BookRepository bookRepository = new BookRepository();
|
||||
private final OrderRepository orderRepository = new OrderRepository();
|
||||
private final OrderUseCase orderUseCase = new OrderUseCase(orderRepository, customerRepository, bookRepository);
|
||||
|
||||
private final Map<String, UUID> customerPhoneUUID = new HashMap<>();
|
||||
private final Map<String, UUID> bookIsbnUUID = new HashMap<>();
|
||||
|
||||
private OrderDTO orderResult;
|
||||
private NotValidOrderException notValidOrderException;
|
||||
private boolean customerNotFoundThrown = false;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
customerRepository.deleteAll();
|
||||
bookRepository.deleteAll();
|
||||
orderRepository.deleteAll();
|
||||
customerPhoneUUID.clear();
|
||||
bookIsbnUUID.clear();
|
||||
orderResult = null;
|
||||
notValidOrderException = null;
|
||||
customerNotFoundThrown = false;
|
||||
}
|
||||
|
||||
@Given("the system has the following customers for order:")
|
||||
public void theSystemHasTheFollowingCustomersForOrder(DataTable dataTable) {
|
||||
List<Map<String, String>> customers = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
for (Map<String, String> customer : customers) {
|
||||
String phone = customer.get("numeroTelephone");
|
||||
Customer newCustomer = Customer.builder()
|
||||
.firstName(customer.get("prenom"))
|
||||
.lastName(customer.get("nom"))
|
||||
.phoneNumber(phone)
|
||||
.loyaltyPoints(Integer.parseInt(customer.get("pointsFidelite")))
|
||||
.build();
|
||||
Customer saved = customerRepository.save(newCustomer);
|
||||
customerPhoneUUID.put(phone, saved.getId());
|
||||
}
|
||||
|
||||
assertEquals(customers.size(), customerRepository.findAll().size());
|
||||
}
|
||||
|
||||
@And("the catalog has the following books for order:")
|
||||
public void theCatalogHasTheFollowingBooksForOrder(DataTable dataTable) {
|
||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
for (Map<String, String> book : books) {
|
||||
String isbn = book.get("isbn");
|
||||
Book newBook = Book.builder()
|
||||
.isbn(isbn)
|
||||
.title(book.get("titre"))
|
||||
.author(book.get("auteur"))
|
||||
.publisher(book.get("editeur"))
|
||||
.publicationDate(LocalDate.parse(book.get("datePublication")))
|
||||
.price(new BigDecimal(book.get("prix")))
|
||||
.stock(Integer.parseInt(book.get("stockInitial")))
|
||||
.categories(List.of(book.get("categories").split(";")))
|
||||
.description(book.get("description"))
|
||||
.language(book.get("langue"))
|
||||
.build();
|
||||
Book saved = bookRepository.save(newBook);
|
||||
bookIsbnUUID.put(isbn, saved.getId());
|
||||
}
|
||||
|
||||
assertEquals(books.size(), bookRepository.findAll().size());
|
||||
}
|
||||
|
||||
@When("I place an order for customer {string} with:")
|
||||
public void iPlaceAnOrderForCustomerWith(String phoneNumber, DataTable dataTable)
|
||||
throws NotValidOrderException, CustomerNotFoundException {
|
||||
Map<String, String> row = dataTable.asMaps(String.class, String.class).getFirst();
|
||||
|
||||
UUID customerId = customerPhoneUUID.get(phoneNumber);
|
||||
UUID livreId = bookIsbnUUID.get(row.get("livreIsbn"));
|
||||
|
||||
AdresseLivraison adresse = new AdresseLivraison(
|
||||
row.get("rue"), row.get("ville"), row.get("codePostal"), row.get("pays")
|
||||
);
|
||||
|
||||
OrderInfo orderInfo = new OrderInfo(
|
||||
customerId,
|
||||
List.of(new LigneCommandeInfo(livreId, Integer.parseInt(row.get("quantite")))),
|
||||
adresse,
|
||||
ModePaiement.valueOf(row.get("modePaiement"))
|
||||
);
|
||||
|
||||
orderResult = orderUseCase.passerCommande(orderInfo);
|
||||
}
|
||||
|
||||
@Then("a new order is created")
|
||||
public void aNewOrderIsCreated() {
|
||||
assertNotNull(orderResult);
|
||||
assertNotNull(orderResult.getCommandeId());
|
||||
}
|
||||
|
||||
@And("the order total is {double}")
|
||||
public void theOrderTotalIs(double expectedTotal) {
|
||||
assertEquals(0, new BigDecimal(String.valueOf(expectedTotal)).compareTo(orderResult.getMontantTotal()));
|
||||
}
|
||||
|
||||
@And("the customer {string} now has {int} loyalty points")
|
||||
public void theCustomerNowHasLoyaltyPoints(String phoneNumber, int expectedPoints) {
|
||||
UUID customerId = customerPhoneUUID.get(phoneNumber);
|
||||
Customer customer = customerRepository.findById(customerId).orElseThrow();
|
||||
assertEquals(expectedPoints, customer.getLoyaltyPoints());
|
||||
}
|
||||
|
||||
@When("I try to place an order for customer {string} with no items:")
|
||||
public void iTryToPlaceAnOrderForCustomerWithNoItems(String phoneNumber, DataTable dataTable) {
|
||||
Map<String, String> row = dataTable.asMaps(String.class, String.class).getFirst();
|
||||
UUID customerId = customerPhoneUUID.get(phoneNumber);
|
||||
|
||||
AdresseLivraison adresse = new AdresseLivraison(
|
||||
row.get("rue"), row.get("ville"), row.get("codePostal"), row.get("pays")
|
||||
);
|
||||
|
||||
OrderInfo orderInfo = new OrderInfo(
|
||||
customerId, List.of(), adresse, ModePaiement.valueOf(row.get("modePaiement"))
|
||||
);
|
||||
|
||||
notValidOrderException = assertThrows(NotValidOrderException.class,
|
||||
() -> orderUseCase.passerCommande(orderInfo));
|
||||
}
|
||||
|
||||
@When("I try to place an order for customer {string} with invalid quantity:")
|
||||
public void iTryToPlaceAnOrderForCustomerWithInvalidQuantity(String phoneNumber, DataTable dataTable) {
|
||||
Map<String, String> row = dataTable.asMaps(String.class, String.class).getFirst();
|
||||
UUID customerId = customerPhoneUUID.get(phoneNumber);
|
||||
UUID livreId = bookIsbnUUID.get(row.get("livreIsbn"));
|
||||
|
||||
AdresseLivraison adresse = new AdresseLivraison(
|
||||
row.get("rue"), row.get("ville"), row.get("codePostal"), row.get("pays")
|
||||
);
|
||||
|
||||
OrderInfo orderInfo = new OrderInfo(
|
||||
customerId,
|
||||
List.of(new LigneCommandeInfo(livreId, Integer.parseInt(row.get("quantite")))),
|
||||
adresse,
|
||||
ModePaiement.valueOf(row.get("modePaiement"))
|
||||
);
|
||||
|
||||
notValidOrderException = assertThrows(NotValidOrderException.class,
|
||||
() -> orderUseCase.passerCommande(orderInfo));
|
||||
}
|
||||
|
||||
@When("I try to place an order for an unknown customer with:")
|
||||
public void iTryToPlaceAnOrderForAnUnknownCustomerWith(DataTable dataTable) {
|
||||
Map<String, String> row = dataTable.asMaps(String.class, String.class).getFirst();
|
||||
UUID unknownId = UUID.randomUUID();
|
||||
UUID livreId = bookIsbnUUID.get(row.get("livreIsbn"));
|
||||
|
||||
AdresseLivraison adresse = new AdresseLivraison(
|
||||
row.get("rue"), row.get("ville"), row.get("codePostal"), row.get("pays")
|
||||
);
|
||||
|
||||
OrderInfo orderInfo = new OrderInfo(
|
||||
unknownId,
|
||||
List.of(new LigneCommandeInfo(livreId, Integer.parseInt(row.get("quantite")))),
|
||||
adresse,
|
||||
ModePaiement.valueOf(row.get("modePaiement"))
|
||||
);
|
||||
|
||||
try {
|
||||
orderUseCase.passerCommande(orderInfo);
|
||||
} catch (CustomerNotFoundException e) {
|
||||
customerNotFoundThrown = true;
|
||||
} catch (NotValidOrderException e) {
|
||||
notValidOrderException = e;
|
||||
}
|
||||
}
|
||||
|
||||
@Then("the order placement fails")
|
||||
public void theOrderPlacementFails() {
|
||||
assertNotNull(notValidOrderException);
|
||||
}
|
||||
|
||||
@Then("the order placement fails with customer not found")
|
||||
public void theOrderPlacementFailsWithCustomerNotFound() {
|
||||
assertTrue(customerNotFoundThrown);
|
||||
}
|
||||
|
||||
@And("I receive a validation order error containing {string}")
|
||||
public void iReceiveAValidationOrderErrorContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, notValidOrderException.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.order.usecase;
|
||||
|
||||
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.exception.CustomerNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.AdresseLivraison;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.LigneCommandeInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.ModePaiement;
|
||||
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.entity.Order;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.exception.NotValidOrderException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.order.repository.OrderRepository;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
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 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;
|
||||
|
||||
@Mock
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@Mock
|
||||
private BookRepository bookRepository;
|
||||
|
||||
@InjectMocks
|
||||
private OrderUseCase orderUseCase;
|
||||
|
||||
private UUID customerId;
|
||||
private UUID bookId;
|
||||
private Customer testCustomer;
|
||||
private Book testBook;
|
||||
private AdresseLivraison adresse;
|
||||
private OrderInfo validOrderInfo;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
customerId = UUID.randomUUID();
|
||||
bookId = UUID.randomUUID();
|
||||
|
||||
testCustomer = Customer.builder()
|
||||
.id(customerId)
|
||||
.firstName("Marie")
|
||||
.lastName("Dupont")
|
||||
.phoneNumber("0612345678")
|
||||
.loyaltyPoints(100)
|
||||
.build();
|
||||
|
||||
testBook = Book.builder()
|
||||
.id(bookId)
|
||||
.isbn("9782016289308")
|
||||
.title("Le Petit Prince")
|
||||
.author("Antoine de Saint-Exupery")
|
||||
.publisher("Gallimard")
|
||||
.publicationDate(LocalDate.of(1943, 4, 6))
|
||||
.price(new BigDecimal("12.90"))
|
||||
.stock(10)
|
||||
.categories(List.of("Roman"))
|
||||
.description("Un classique")
|
||||
.language("FR")
|
||||
.build();
|
||||
|
||||
adresse = new AdresseLivraison("1 rue de Paris", "Paris", "75001", "France");
|
||||
|
||||
validOrderInfo = new OrderInfo(
|
||||
customerId,
|
||||
List.of(new LigneCommandeInfo(bookId, 2)),
|
||||
adresse,
|
||||
ModePaiement.CB
|
||||
);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("PasserCommande tests")
|
||||
class PasserCommandeTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should place order when valid data is provided")
|
||||
void testPasserCommandeWithValidData() throws NotValidOrderException, CustomerNotFoundException {
|
||||
when(customerRepository.findById(customerId)).thenReturn(Optional.of(testCustomer));
|
||||
when(bookRepository.findById(bookId)).thenReturn(Optional.of(testBook));
|
||||
when(customerRepository.save(any(Customer.class))).thenReturn(testCustomer);
|
||||
|
||||
UUID orderId = UUID.randomUUID();
|
||||
Order savedOrder = Order.builder()
|
||||
.id(orderId)
|
||||
.clientId(customerId)
|
||||
.montantTotal(new BigDecimal("25.80"))
|
||||
.pointsFideliteGagnes(25)
|
||||
.build();
|
||||
when(orderRepository.save(any(Order.class))).thenReturn(savedOrder);
|
||||
|
||||
OrderDTO result = orderUseCase.passerCommande(validOrderInfo);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(orderId, result.getCommandeId());
|
||||
verify(orderRepository, times(1)).save(any(Order.class));
|
||||
verify(customerRepository, times(1)).save(any(Customer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when customer does not exist")
|
||||
void testPasserCommandeWithUnknownCustomer() {
|
||||
when(customerRepository.findById(customerId)).thenReturn(Optional.empty());
|
||||
|
||||
assertThrows(CustomerNotFoundException.class,
|
||||
() -> orderUseCase.passerCommande(validOrderInfo));
|
||||
|
||||
verify(orderRepository, never()).save(any(Order.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when order has no items")
|
||||
void testPasserCommandeWithNoItems() {
|
||||
OrderInfo emptyOrder = new OrderInfo(customerId, List.of(), adresse, ModePaiement.CB);
|
||||
|
||||
assertThrows(NotValidOrderException.class,
|
||||
() -> orderUseCase.passerCommande(emptyOrder));
|
||||
|
||||
verify(orderRepository, never()).save(any(Order.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when quantity is zero or negative")
|
||||
void testPasserCommandeWithInvalidQuantity() {
|
||||
OrderInfo invalidQty = new OrderInfo(
|
||||
customerId,
|
||||
List.of(new LigneCommandeInfo(bookId, 0)),
|
||||
adresse,
|
||||
ModePaiement.CB
|
||||
);
|
||||
|
||||
assertThrows(NotValidOrderException.class,
|
||||
() -> orderUseCase.passerCommande(invalidQty));
|
||||
|
||||
verify(orderRepository, never()).save(any(Order.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when clientId is null")
|
||||
void testPasserCommandeWithNullClientId() {
|
||||
OrderInfo nullClient = new OrderInfo(
|
||||
null,
|
||||
List.of(new LigneCommandeInfo(bookId, 1)),
|
||||
adresse,
|
||||
ModePaiement.CB
|
||||
);
|
||||
|
||||
assertThrows(NotValidOrderException.class,
|
||||
() -> orderUseCase.passerCommande(nullClient));
|
||||
|
||||
verify(orderRepository, never()).save(any(Order.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when payment method is null")
|
||||
void testPasserCommandeWithNullModePaiement() {
|
||||
OrderInfo nullPayment = new OrderInfo(
|
||||
customerId,
|
||||
List.of(new LigneCommandeInfo(bookId, 1)),
|
||||
adresse,
|
||||
null
|
||||
);
|
||||
|
||||
assertThrows(NotValidOrderException.class,
|
||||
() -> orderUseCase.passerCommande(nullPayment));
|
||||
|
||||
verify(orderRepository, never()).save(any(Order.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("FindOrder tests")
|
||||
class FindOrderTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return order when ID exists")
|
||||
void testFindOrderById() {
|
||||
UUID orderId = UUID.randomUUID();
|
||||
Order order = Order.builder()
|
||||
.id(orderId)
|
||||
.clientId(customerId)
|
||||
.montantTotal(new BigDecimal("25.80"))
|
||||
.pointsFideliteGagnes(25)
|
||||
.build();
|
||||
|
||||
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
|
||||
|
||||
Optional<OrderDTO> result = orderUseCase.findOrderById(orderId);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(orderId, result.get().getCommandeId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return empty Optional when ID does not exist")
|
||||
void testFindOrderByIdNotFound() {
|
||||
UUID nonExistentId = UUID.randomUUID();
|
||||
when(orderRepository.findById(nonExistentId)).thenReturn(Optional.empty());
|
||||
|
||||
Optional<OrderDTO> result = orderUseCase.findOrderById(nonExistentId);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user