Compare commits
9 Commits
main
...
276b6e4fc6
Author | SHA1 | Date | |
---|---|---|---|
276b6e4fc6 | |||
d71ffcc9ff | |||
568d67a437 | |||
f6e560f23b | |||
8f76a6fbd4 | |||
0bb4a21c95 | |||
9d49b597e9 | |||
fedaecda21 | |||
c2208d010b |
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
12
.idea/misc.xml
generated
Normal file
12
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="openjdk-23" project-jdk-type="JavaSDK" />
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@@ -0,0 +1,23 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class BookDTO {
|
||||
private final String isbn;
|
||||
private final String title;
|
||||
private final String author;
|
||||
private final String publisher;
|
||||
private final Date date;
|
||||
private final double price;
|
||||
private final int initialStock;
|
||||
private final ArrayList<String> categories;
|
||||
private final String description;
|
||||
private final String language;
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
public record BookInfo(String isbn,
|
||||
String title,
|
||||
String author,
|
||||
String publisher,
|
||||
Date date,
|
||||
double price,
|
||||
int initialStock,
|
||||
ArrayList<String>categories,
|
||||
String description,
|
||||
String language){
|
||||
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.converter;
|
||||
|
||||
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.entity.Book;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
|
||||
public final class BookConverter {
|
||||
private BookConverter(){
|
||||
|
||||
}
|
||||
|
||||
public static Book toDomain(BookInfo newBook) {
|
||||
return Book.builder()
|
||||
.isbn(newBook.isbn())
|
||||
.title(newBook.title())
|
||||
.author(newBook.author())
|
||||
.publisher(newBook.publisher())
|
||||
.date(newBook.date())
|
||||
.price(newBook.price())
|
||||
.initialStock(newBook.initialStock())
|
||||
.categories(newBook.categories())
|
||||
.description(newBook.description())
|
||||
.language(newBook.language())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static BookDTO toDTO(Book book) {
|
||||
return BookDTO.builder()
|
||||
.isbn(book.getIsbn())
|
||||
.title(book.getTitle())
|
||||
.author(book.getAuthor())
|
||||
.publisher(book.getPublisher())
|
||||
.date(book.getDate())
|
||||
.price(book.getPrice())
|
||||
.initialStock(book.getInitialStock())
|
||||
.categories(book.getCategories())
|
||||
.description(book.getDescription())
|
||||
.language(book.getLanguage())
|
||||
.build();
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.entity;
|
||||
|
||||
|
||||
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.IllegalBookStockException;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class Book {
|
||||
|
||||
private String isbn;
|
||||
private String title;
|
||||
private String author;
|
||||
private String publisher;
|
||||
private Date date;
|
||||
private double price;
|
||||
private int initialStock;
|
||||
private ArrayList<String> categories;
|
||||
private String description;
|
||||
private String language;
|
||||
|
||||
public void removeStock(int stockToRemove) throws IllegalBookStockException{
|
||||
if (initialStock - stockToRemove <0){ throw new IllegalBookStockException(stockToRemove,initialStock); }
|
||||
initialStock = initialStock - stockToRemove;
|
||||
}
|
||||
|
||||
public void addStock(int stockToAdd) {
|
||||
initialStock = initialStock + stockToAdd;
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
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 BookNotFoundException(String isbn) {
|
||||
super(MessageFormat.format(THE_BOOK_WITH_ISBN_DOES_NOT_EXIST_MESSAGE, isbn));
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
public class IllegalBookStockException extends Exception {
|
||||
|
||||
public static final String CANNOT_REMOVE_STOCK = "Cannot remove {0} stock from {1} points";
|
||||
|
||||
public IllegalBookStockException(int needed, int actual) {
|
||||
super(MessageFormat.format(CANNOT_REMOVE_STOCK, needed,
|
||||
actual));
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
|
||||
|
||||
public class NotValidBookException extends Exception {
|
||||
|
||||
public NotValidBookException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor
|
||||
public final class BookRepository {
|
||||
private final List<Book> books = new ArrayList<>();
|
||||
|
||||
public List<Book> findAll() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void deleteAll() {
|
||||
books.clear();
|
||||
}
|
||||
|
||||
public Book save(Book newBook) {
|
||||
Optional<Book> optionalBookWithSameId = this.findByISBN(newBook.getIsbn());
|
||||
optionalBookWithSameId.ifPresent(books::remove);
|
||||
this.books.add(newBook);
|
||||
return newBook;
|
||||
}
|
||||
|
||||
public Optional<Book> findByISBN(String isbn) {
|
||||
|
||||
return this.books.stream()
|
||||
.filter(book -> book.getIsbn().equals(isbn))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public boolean existsByISBN(String isbn) {
|
||||
return this.books.stream()
|
||||
.anyMatch(book -> book.getIsbn().equals(isbn));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void delete(Book book) {
|
||||
this.books.remove(book);
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
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.IllegalBookStockException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.validator.BookValidator;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class BookUseCase {
|
||||
|
||||
private final BookRepository bookRepository;
|
||||
|
||||
public BookUseCase(BookRepository bookRepository) {
|
||||
this.bookRepository = bookRepository;
|
||||
}
|
||||
|
||||
public String registerBook(BookInfo newBook) throws NotValidBookException {
|
||||
BookValidator.validate(newBook);
|
||||
Book bookToRegister = BookConverter.toDomain(newBook);
|
||||
Book bookToRegistered = bookRepository.save(bookToRegister);
|
||||
return bookToRegistered.getIsbn();
|
||||
}
|
||||
|
||||
public Optional<BookDTO> findBookByISBN(String isbn) {
|
||||
Optional<Book> optionalBook = bookRepository.findByISBN(isbn);
|
||||
return optionalBook.map(BookConverter::toDTO);
|
||||
}
|
||||
|
||||
public BookDTO updateBook(String isbn, BookInfo bookInfo)
|
||||
throws BookNotFoundException, NotValidBookException {
|
||||
BookValidator.validate(bookInfo);
|
||||
Book bookByISBN = getBookIfDoesNotExistThrowBookNotFoundException(
|
||||
isbn);
|
||||
Book book = Book.builder()
|
||||
.isbn(isbn)
|
||||
.title(bookInfo.title())
|
||||
.author(bookInfo.author())
|
||||
.publisher(bookInfo.publisher())
|
||||
.date(bookInfo.date())
|
||||
.price(bookInfo.price())
|
||||
.initialStock(bookInfo.initialStock())
|
||||
.categories(bookInfo.categories())
|
||||
.description(bookInfo.description())
|
||||
.language(bookInfo.language())
|
||||
.build();
|
||||
Book updatedBook = bookRepository.save(book);
|
||||
return BookConverter.toDTO(updatedBook);
|
||||
}
|
||||
|
||||
public void deleteBook(String isbn) throws BookNotFoundException {
|
||||
Book bookToDelete = getBookIfDoesNotExistThrowBookNotFoundException(isbn);
|
||||
this.bookRepository.delete(bookToDelete);
|
||||
}
|
||||
|
||||
public int addStock(String isbn, int stockToAdd) throws BookNotFoundException {
|
||||
Book bookToAddStock = getBookIfDoesNotExistThrowBookNotFoundException(isbn);
|
||||
bookToAddStock.addStock(stockToAdd);
|
||||
bookRepository.save(bookToAddStock);
|
||||
return bookToAddStock.getInitialStock();
|
||||
}
|
||||
|
||||
public int subtractStock(String isbn, int loyaltyPointToRemove)
|
||||
throws BookNotFoundException, IllegalBookStockException {
|
||||
Book bookToSubtractStock = getBookIfDoesNotExistThrowBookNotFoundException(isbn);
|
||||
bookToSubtractStock.removeStock(loyaltyPointToRemove);
|
||||
bookRepository.save(bookToSubtractStock);
|
||||
return bookToSubtractStock.getInitialStock();
|
||||
}
|
||||
|
||||
private Book getBookIfDoesNotExistThrowBookNotFoundException(String isbn)
|
||||
throws BookNotFoundException {
|
||||
Optional<Book> optionalBookById = bookRepository.findByISBN(isbn);
|
||||
if (optionalBookById.isEmpty()) {
|
||||
throw new BookNotFoundException(isbn);
|
||||
}
|
||||
return optionalBookById.get();
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
|
||||
public final class BookValidator {
|
||||
|
||||
public static final String ISBN_IS_NOT_VALID = "ISBN is not valid";
|
||||
public static final String ISBN_CANNOT_BE_BLANK = "ISBN cannot be blank";
|
||||
public static final String TITLE_CANNOT_BE_BLANK = "Title cannot be blank";
|
||||
public static final String AUTHOR_CANNOT_BE_BLANK = "Author cannot be blank";
|
||||
public static final String PUBLISHER_CANNOT_BE_BLANK = "Publisher cannot be blank";
|
||||
public static final String PRICE_CANNOT_BE_NEGATIVE = "Price cannot be negative";
|
||||
public static final String PRICE_CANNOT_BE_EQUAL_TO_ZERO = "Price cannot be equal to zero";
|
||||
public static final String INITIAL_STOCK_CANNOT_BE_NEGATIVE = "Stock cannot be negative";
|
||||
|
||||
public static final String ISBN_REGEX = "\\d{13}";
|
||||
|
||||
private BookValidator() {
|
||||
|
||||
}
|
||||
|
||||
public static void validate(BookInfo newBook) throws NotValidBookException {
|
||||
validateAuthor(newBook);
|
||||
validateTitle(newBook);
|
||||
validateISBN(newBook);
|
||||
}
|
||||
|
||||
private static void validateISBN(BookInfo newBook)
|
||||
throws NotValidBookException {
|
||||
if (newBook.isbn().isBlank()) {
|
||||
throw new NotValidBookException(ISBN_CANNOT_BE_BLANK);
|
||||
}
|
||||
if (!newBook.isbn().matches(ISBN_REGEX)) {
|
||||
throw new NotValidBookException(ISBN_IS_NOT_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateTitle(BookInfo newBook) throws NotValidBookException {
|
||||
if (newBook.title().isBlank()) {
|
||||
throw new NotValidBookException(TITLE_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateAuthor(BookInfo newBook) throws NotValidBookException {
|
||||
if (newBook.author().isBlank()) {
|
||||
throw new NotValidBookException(AUTHOR_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePublisher(BookInfo newBook) throws NotValidBookException {
|
||||
if (newBook.publisher().isBlank()){
|
||||
throw new NotValidBookException(PUBLISHER_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePrice(BookInfo newBook) throws NotValidBookException {
|
||||
if (newBook.price() < 0){
|
||||
throw new NotValidBookException(PRICE_CANNOT_BE_NEGATIVE);
|
||||
} else if (newBook.price() == 0){
|
||||
throw new NotValidBookException(PRICE_CANNOT_BE_EQUAL_TO_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateInitialStock(BookInfo newBook) throws NotValidBookException {
|
||||
if (newBook.initialStock() < 0){
|
||||
throw new NotValidBookException(INITIAL_STOCK_CANNOT_BE_NEGATIVE);
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,6 +8,7 @@ import lombok.Getter;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
|
||||
public class Customer {
|
||||
private UUID id;
|
||||
private String firstName;
|
||||
|
@@ -0,0 +1,15 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import java.util.UUID;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class SubscriptionDTO {
|
||||
private final UUID id;
|
||||
private final UUID customerId;
|
||||
private final Integer duration;
|
||||
private final String paymentMethod;
|
||||
private final String debutDate;
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record SubscriptionInfo(UUID customerId, Integer duration, String paymentMethod) {
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.converter;
|
||||
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity.Subscription;
|
||||
|
||||
public final class SubscriptionConverter {
|
||||
private SubscriptionConverter() {
|
||||
|
||||
}
|
||||
|
||||
public static Subscription toDomain(SubscriptionInfo newSubscription) {
|
||||
return Subscription.builder()
|
||||
.customerId(newSubscription.customerId())
|
||||
.duration(newSubscription.duration())
|
||||
.paymentMethod(newSubscription.paymentMethod())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static SubscriptionDTO toDTO(Subscription subscription) {
|
||||
return SubscriptionDTO.builder()
|
||||
.id(subscription.getId())
|
||||
.customerId(subscription.getCustomerId())
|
||||
.duration(subscription.getDuration())
|
||||
.paymentMethod(subscription.getPaymentMethod())
|
||||
.debutDate(subscription.getDebutDate())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class Subscription {
|
||||
private UUID id;
|
||||
private UUID customerId;
|
||||
private Integer duration;
|
||||
private String paymentMethod;
|
||||
private String debutDate;
|
||||
|
||||
public void setRandomUUID() {
|
||||
this.id = UUID.randomUUID();
|
||||
}
|
||||
|
||||
public void setDebutDate(String debutDate) {
|
||||
this.debutDate = LocalDate.now().toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception;
|
||||
|
||||
public class NotValidSubscriptionException extends Exception {
|
||||
|
||||
public NotValidSubscriptionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
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 SubscriptionNotFoundException(UUID uuid) {
|
||||
super(MessageFormat.format(THE_SUBSCRIPTION_WITH_ID_DOES_NOT_EXIST_MESSAGE, uuid));
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity.Subscription;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
public class SubscriptionRepository {
|
||||
private final List<Subscription> subscriptions = new ArrayList<>();
|
||||
|
||||
public List<Subscription> findAll() {
|
||||
return subscriptions;
|
||||
}
|
||||
|
||||
public Subscription save(Subscription newSubscription) {
|
||||
Optional<Subscription> optionalSubscriptionWithSameId = this.findByCustomerId(newSubscription.getCustomerId());
|
||||
optionalSubscriptionWithSameId.ifPresentOrElse(subscriptions::remove, newSubscription::setRandomUUID);
|
||||
this.subscriptions.add(newSubscription);
|
||||
return newSubscription;
|
||||
}
|
||||
|
||||
public Optional<Subscription> findByCustomerId(UUID uuid) {
|
||||
return this.subscriptions.stream()
|
||||
.filter(subscription -> subscription.getCustomerId().equals(uuid))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public boolean existsById(UUID uuid) {
|
||||
return this.subscriptions.stream()
|
||||
.anyMatch(subscription -> subscription.getId().equals(uuid));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.converter.SubscriptionConverter;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity.Subscription;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.SubscriptionNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.repository.SubscriptionRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.validator.SubscriptionValidator;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SubscriptionUseCase {
|
||||
|
||||
private final SubscriptionRepository subscriptionRepository;
|
||||
|
||||
public SubscriptionUseCase(SubscriptionRepository subscriptionRepository) {
|
||||
this.subscriptionRepository = subscriptionRepository;
|
||||
}
|
||||
|
||||
public UUID registerSubscription(SubscriptionInfo newSubscription) throws NotValidSubscriptionException {
|
||||
SubscriptionValidator.validate(newSubscription);
|
||||
Subscription subscriptionToRegister = SubscriptionConverter.toDomain(newSubscription);
|
||||
Subscription subscriptionToRegistered = subscriptionRepository.save(subscriptionToRegister);
|
||||
if (subscriptionToRegistered.getDuration() <= 0) {
|
||||
throw new NotValidSubscriptionException("Duration must be positive");
|
||||
}
|
||||
return subscriptionToRegistered.getId();
|
||||
}
|
||||
|
||||
public Optional<SubscriptionDTO> findSubscriptionByCustomerId(UUID customerId) {
|
||||
Optional<Subscription> optionalSubscription = subscriptionRepository.findByCustomerId(customerId);
|
||||
return optionalSubscription.map(SubscriptionConverter::toDTO);
|
||||
}
|
||||
|
||||
private boolean getSubscriptionIfDoesNotExistThrowSubscriptionNotFoundException(UUID uuid)
|
||||
throws SubscriptionNotFoundException {
|
||||
if (subscriptionRepository.existsById(uuid)) {
|
||||
throw new SubscriptionNotFoundException(uuid);
|
||||
}
|
||||
return subscriptionRepository.existsById(uuid);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.NotValidCustomerException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException;
|
||||
|
||||
public class SubscriptionValidator {
|
||||
|
||||
public static final String CUSTOMER_ID_CANNOT_BE_NULL = "Customer ID cannot be null";
|
||||
public static final String DURATION_CANNOT_BE_NULL = "Duration is not valid";
|
||||
public static final String PAYMENT_METHOD_CANNOT_BE_BLANK = "Payment Method cannot be blank";
|
||||
|
||||
|
||||
private SubscriptionValidator() {
|
||||
|
||||
}
|
||||
|
||||
public static void validate(SubscriptionInfo newSubscription) throws fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException {
|
||||
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 validatePaymentMethod(SubscriptionInfo newSubscription) throws fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException {
|
||||
if (newSubscription.paymentMethod().isBlank()) {
|
||||
throw new NotValidSubscriptionException(PAYMENT_METHOD_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.converter;
|
||||
|
||||
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 org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
@DisplayName("BookConverter Unit Tests")
|
||||
public class BookConverterTest {
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDomain() method tests")
|
||||
class ToDomainTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert BookInfo to Book domain object")
|
||||
void shouldConvertBookInfoToDomain() {
|
||||
// Given
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookInfo = new BookInfo("1234567891234", "Livre", "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
// When
|
||||
Book result = BookConverter.toDomain(bookInfo);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(bookInfo.isbn(), result.getIsbn());
|
||||
assertEquals(bookInfo.title(), result.getTitle());
|
||||
assertEquals(bookInfo.author(), result.getAuthor());
|
||||
assertEquals(bookInfo.publisher(), result.getPublisher());
|
||||
assertEquals(bookInfo.date(), result.getDate());
|
||||
assertEquals(bookInfo.price(), result.getPrice());
|
||||
assertEquals(bookInfo.initialStock(), result.getInitialStock());
|
||||
assertEquals(bookInfo.categories(), result.getCategories());
|
||||
assertEquals(bookInfo.description(), result.getDescription());
|
||||
assertEquals(bookInfo.language(), result.getLanguage());
|
||||
}
|
||||
}
|
||||
@Nested
|
||||
@DisplayName("toDTO() method tests")
|
||||
class ToDTOTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert Book domain object to BookDTO with all fields mapped correctly")
|
||||
void shouldConvertBookToDTO() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
Book book = Book.builder()
|
||||
.isbn("1234567890123")
|
||||
.title("Livre 1")
|
||||
.author("John Updated")
|
||||
.publisher("Editeur")
|
||||
.date(Date.from(Instant.now()))
|
||||
.price(4.99)
|
||||
.initialStock(42)
|
||||
.categories(categories)
|
||||
.description("Description")
|
||||
.language("Francais")
|
||||
.build();
|
||||
|
||||
BookDTO result = BookConverter.toDTO(book);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(book.getIsbn(), result.getIsbn());
|
||||
assertEquals(book.getTitle(), result.getTitle());
|
||||
assertEquals(book.getAuthor(), result.getAuthor());
|
||||
assertEquals(book.getPublisher(), result.getPublisher());
|
||||
assertEquals(book.getDate(), result.getDate());
|
||||
assertEquals(book.getPrice(), result.getPrice());
|
||||
assertEquals(book.getInitialStock(), result.getInitialStock());
|
||||
assertEquals(book.getCategories(), result.getCategories());
|
||||
assertEquals(book.getDescription(), result.getDescription());
|
||||
assertEquals(book.getLanguage(), result.getLanguage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null values properly when converting between objects")
|
||||
void shouldHandleNullValuesGracefully() {
|
||||
Book book = Book.builder()
|
||||
.isbn("1234567890123")
|
||||
.title("Null")
|
||||
.author("Null")
|
||||
.publisher("Null")
|
||||
.date(null)
|
||||
.price(4.99)
|
||||
.initialStock(42)
|
||||
.categories(null)
|
||||
.description(null)
|
||||
.language(null)
|
||||
.build();
|
||||
|
||||
BookDTO result = BookConverter.toDTO(book);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(book.getIsbn(), result.getIsbn());
|
||||
assertEquals(book.getTitle(), result.getTitle());
|
||||
assertEquals(book.getAuthor(), result.getAuthor());
|
||||
assertEquals(book.getPublisher(), result.getPublisher());
|
||||
assertNull(result.getDate());
|
||||
assertEquals(book.getPrice(), result.getPrice());
|
||||
assertEquals(book.getInitialStock(), result.getInitialStock());
|
||||
assertNull(result.getCategories());
|
||||
assertNull(result.getDescription());
|
||||
assertNull(result.getLanguage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should preserve empty string values during conversion")
|
||||
void shouldPreserveEmptyStrings() {
|
||||
BookInfo bookInfo = new BookInfo("1234567890123", "e", "e","e",null,1.2,5,null,"","");
|
||||
|
||||
Book domainResult = BookConverter.toDomain(bookInfo);
|
||||
BookDTO result = BookConverter.toDTO(domainResult);
|
||||
|
||||
|
||||
assertEquals(bookInfo.isbn(), result.getIsbn()); //ISBN ne peut pas etre vide
|
||||
assertEquals(bookInfo.title(), result.getTitle()); // Le titre ne peut pas etre vide
|
||||
assertEquals(bookInfo.author(), result.getAuthor()); // L'auteur ne peut pas etre vide
|
||||
assertEquals(bookInfo.publisher(), result.getPublisher()); // L'editeur ne peut pas etre vide
|
||||
assertEquals(null, result.getDate());
|
||||
assertEquals(bookInfo.price(), result.getPrice());
|
||||
assertEquals(bookInfo.initialStock(), result.getInitialStock());
|
||||
assertEquals(null, result.getCategories());
|
||||
assertEquals("", result.getDescription());
|
||||
assertEquals("", result.getLanguage());
|
||||
}
|
||||
}
|
@@ -0,0 +1,232 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.entity;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.IllegalBookStockException;
|
||||
import io.cucumber.java.bs.A;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
class BookTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Builder should create a valid Book instance")
|
||||
void testBookBuilder() {
|
||||
String ISBN = "1234567890123";
|
||||
String title = "LivreRandom";
|
||||
String author = "John Doe";
|
||||
String publisher = "EditeurRandom";
|
||||
Date date = Date.from(Instant.now());
|
||||
double price = 5.99;
|
||||
int initialStock = 15;
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
String description = "Je suis un livre qui contient des phrases composees de mots qui sont eux memes composes de lettres faits a partir d'encre sur du papier relie par une couverture cartonnee";
|
||||
String language = "Francais";
|
||||
|
||||
Book book = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(title)
|
||||
.author(author)
|
||||
.publisher(publisher)
|
||||
.date(date)
|
||||
.price(price)
|
||||
.initialStock(initialStock)
|
||||
.categories(categories)
|
||||
.description(description)
|
||||
.language(language)
|
||||
.build();
|
||||
|
||||
assertEquals(ISBN, book.getIsbn());
|
||||
assertEquals(title, book.getTitle());
|
||||
assertEquals(author, book.getAuthor());
|
||||
assertEquals(publisher, book.getPublisher());
|
||||
assertEquals(date, book.getDate());
|
||||
assertEquals(price, book.getPrice());
|
||||
assertEquals(initialStock, book.getInitialStock());
|
||||
assertEquals(categories, book.getCategories());
|
||||
assertEquals(description, book.getDescription());
|
||||
assertEquals(language, book.getLanguage());
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Book stock Tests")
|
||||
class BookStockTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("addStock should correctly increment stock")
|
||||
void testAddStock() {
|
||||
|
||||
String ISBN = "1234567890123";
|
||||
String title = "LivreRandom";
|
||||
String author = "John Doe";
|
||||
String publisher = "EditeurRandom";
|
||||
Date date = Date.from(Instant.now());
|
||||
double price = 5.99;
|
||||
int initialStock = 50;
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
String description = "Je suis un livre qui contient des phrases composees de mots qui sont eux memes composes de lettres faits a partir d'encre sur du papier relie par une couverture cartonnee";
|
||||
String language = "Francais";
|
||||
Book book = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(title)
|
||||
.author(author)
|
||||
.publisher(publisher)
|
||||
.date(date)
|
||||
.price(price)
|
||||
.initialStock(initialStock)
|
||||
.categories(categories)
|
||||
.description(description)
|
||||
.language(language)
|
||||
.build();
|
||||
int stockToAdd = 25;
|
||||
int expectedStock = 75;
|
||||
|
||||
book.addStock(stockToAdd);
|
||||
|
||||
assertEquals(expectedStock, book.getInitialStock());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("addStock should handle zero points correctly")
|
||||
void testAddZeroStock() {
|
||||
String ISBN = "1234567890123";
|
||||
String title = "LivreRandom";
|
||||
String author = "John Doe";
|
||||
String publisher = "EditeurRandom";
|
||||
Date date = Date.from(Instant.now());
|
||||
double price = 5.99;
|
||||
int initialStock = 50;
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
String description = "Je suis un livre qui contient des phrases composees de mots qui sont eux memes composes de lettres faits a partir d'encre sur du papier relie par une couverture cartonnee";
|
||||
String language = "Francais";
|
||||
Book book = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(title)
|
||||
.author(author)
|
||||
.publisher(publisher)
|
||||
.date(date)
|
||||
.price(price)
|
||||
.initialStock(initialStock)
|
||||
.categories(categories)
|
||||
.description(description)
|
||||
.language(language)
|
||||
.build();
|
||||
|
||||
book.addStock(0);
|
||||
|
||||
assertEquals(50, book.getInitialStock());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("removeStock should correctly decrement points")
|
||||
void testRemoveStock() throws IllegalBookStockException {
|
||||
String ISBN = "1234567890123";
|
||||
String title = "LivreRandom";
|
||||
String author = "John Doe";
|
||||
String publisher = "EditeurRandom";
|
||||
Date date = Date.from(Instant.now());
|
||||
double price = 5.99;
|
||||
int initialStock = 50;
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
String description = "Je suis un livre qui contient des phrases composees de mots qui sont eux memes composes de lettres faits a partir d'encre sur du papier relie par une couverture cartonnee";
|
||||
String language = "Francais";
|
||||
Book book = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(title)
|
||||
.author(author)
|
||||
.publisher(publisher)
|
||||
.date(date)
|
||||
.price(price)
|
||||
.initialStock(initialStock)
|
||||
.categories(categories)
|
||||
.description(description)
|
||||
.language(language)
|
||||
.build();
|
||||
int stockToRemove = 20;
|
||||
int expectedStock = 30;
|
||||
|
||||
book.removeStock(stockToRemove);
|
||||
|
||||
assertEquals(expectedStock, book.getInitialStock());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("removeStock should throw exception when trying to remove more points than available")
|
||||
void testRemoveTooManyStock() {
|
||||
String ISBN = "1234567890123";
|
||||
String title = "LivreRandom";
|
||||
String author = "John Doe";
|
||||
String publisher = "EditeurRandom";
|
||||
Date date = Date.from(Instant.now());
|
||||
double price = 5.99;
|
||||
int initialStock = 50;
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
String description = "Je suis un livre qui contient des phrases composees de mots qui sont eux memes composes de lettres faits a partir d'encre sur du papier relie par une couverture cartonnee";
|
||||
String language = "Francais";
|
||||
Book book = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(title)
|
||||
.author(author)
|
||||
.publisher(publisher)
|
||||
.date(date)
|
||||
.price(price)
|
||||
.initialStock(initialStock)
|
||||
.categories(categories)
|
||||
.description(description)
|
||||
.language(language)
|
||||
.build();
|
||||
int pointsToRemove = 75;
|
||||
|
||||
IllegalBookStockException exception = assertThrows(
|
||||
IllegalBookStockException.class,
|
||||
() -> book.removeStock(pointsToRemove)
|
||||
);
|
||||
|
||||
assertEquals(50, book.getInitialStock());
|
||||
assertTrue(exception.getMessage().contains(String.valueOf(pointsToRemove)));
|
||||
assertTrue(exception.getMessage().contains(String.valueOf(book.getInitialStock())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("removeStock should handle removing zero points correctly")
|
||||
void testRemoveZeroStock() throws IllegalBookStockException {
|
||||
String ISBN = "1234567890123";
|
||||
String title = "LivreRandom";
|
||||
String author = "John Doe";
|
||||
String publisher = "EditeurRandom";
|
||||
Date date = Date.from(Instant.now());
|
||||
double price = 5.99;
|
||||
int initialStock = 50;
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
String description = "Je suis un livre qui contient des phrases composees de mots qui sont eux memes composes de lettres faits a partir d'encre sur du papier relie par une couverture cartonnee";
|
||||
String language = "Francais";
|
||||
Book book = Book.builder()
|
||||
.isbn(ISBN)
|
||||
.title(title)
|
||||
.author(author)
|
||||
.publisher(publisher)
|
||||
.date(date)
|
||||
.price(price)
|
||||
.initialStock(initialStock)
|
||||
.categories(categories)
|
||||
.description(description)
|
||||
.language(language)
|
||||
.build();
|
||||
|
||||
book.removeStock(0);
|
||||
|
||||
assertEquals(50, book.getInitialStock());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class BookNotFoundExceptionTest {
|
||||
|
||||
private String randomISBN(){
|
||||
Random r = new Random();
|
||||
String ret = "";
|
||||
for(int i=0;i<13;i++){
|
||||
int e = r.nextInt()%10;
|
||||
ret = ret + e;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception message should contain the UUID provided")
|
||||
void testExceptionMessageContainsISBN() {
|
||||
String ISBN = randomISBN();
|
||||
|
||||
BookNotFoundException exception = new BookNotFoundException(ISBN);
|
||||
|
||||
String expectedMessage = String.format("The book with ISBN %s does not exist", ISBN);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should use the correct constant message format")
|
||||
void testExceptionUsesConstantMessageFormat() {
|
||||
String ISBN = randomISBN();
|
||||
|
||||
BookNotFoundException exception = new BookNotFoundException(ISBN);
|
||||
|
||||
String expectedFormatWithPlaceholder = "The book with ISBN {0} does not exist";
|
||||
assertEquals(BookNotFoundException.THE_BOOK_WITH_ISBN_DOES_NOT_EXIST_MESSAGE,
|
||||
expectedFormatWithPlaceholder);
|
||||
assertTrue(exception.getMessage().contains(ISBN));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
String ISBN = randomISBN();
|
||||
|
||||
try {
|
||||
throw new BookNotFoundException(ISBN);
|
||||
} catch (BookNotFoundException e) {
|
||||
String expectedMessage = String.format("The book with ISBN %s does not exist", ISBN);
|
||||
assertEquals(expectedMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.IllegalBookStockException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class IllegalBookStockExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception message should contain the needed and actual stock")
|
||||
void testExceptionMessageContainsStock() {
|
||||
int neededStock = 100;
|
||||
int actualStock = 50;
|
||||
|
||||
IllegalBookStockException exception = new IllegalBookStockException(neededStock, actualStock);
|
||||
|
||||
String expectedMessage = "Cannot remove 100 stock from 50 stock";
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"100, 50",
|
||||
"75, 25",
|
||||
"200, 150",
|
||||
"1000, 750"
|
||||
})
|
||||
@DisplayName("Exception message should be formatted correctly for different stock values")
|
||||
void testExceptionMessageForDifferentStockValues(int neededStock, int actualStock) {
|
||||
IllegalBookStockException exception = new IllegalBookStockException(neededStock, actualStock);
|
||||
|
||||
String expectedMessage = MessageFormat.format(IllegalBookStockException.CANNOT_REMOVE_STOCK, neededStock, actualStock);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should use the correct constant message format")
|
||||
void testExceptionUsesConstantMessageFormat() {
|
||||
int neededStock = 100;
|
||||
int actualStock = 50;
|
||||
|
||||
IllegalBookStockException exception = new IllegalBookStockException(neededStock, actualStock);
|
||||
|
||||
String expectedFormatWithPlaceholder = "Cannot remove {0} stock from {1} stock";
|
||||
assertEquals(IllegalBookStockException.CANNOT_REMOVE_STOCK,
|
||||
expectedFormatWithPlaceholder);
|
||||
assertTrue(exception.getMessage().contains(String.valueOf(neededStock)));
|
||||
assertTrue(exception.getMessage().contains(String.valueOf(actualStock)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
int neededStock = 100;
|
||||
int actualStock = 50;
|
||||
|
||||
try {
|
||||
throw new IllegalBookStockException(neededStock, actualStock);
|
||||
} catch (IllegalBookStockException e) {
|
||||
String expectedMessage = String.format("Cannot remove %d stock from %d stock", neededStock, actualStock);
|
||||
assertEquals(expectedMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.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 NotValidBookExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be created with the provided message")
|
||||
void testExceptionCreation() {
|
||||
String errorMessage = "Customer data is not valid";
|
||||
|
||||
NotValidBookException exception = new NotValidBookException(errorMessage);
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"ISBN format is invalid",
|
||||
"Title cannot be empty",
|
||||
"Author cannot be empty",
|
||||
"Publisher cannot be empty",
|
||||
"Price needs to be positive",
|
||||
"Stock cannot go below 0",
|
||||
})
|
||||
@DisplayName("Exception should handle different validation messages")
|
||||
void testExceptionWithDifferentMessages(String errorMessage) {
|
||||
NotValidBookException exception = new NotValidBookException(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(NotValidBookException.class, () -> {
|
||||
throw new NotValidBookException(errorMessage);
|
||||
});
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be catchable as a general Exception")
|
||||
void testExceptionInheritance() {
|
||||
String errorMessage = "Invalid book data";
|
||||
|
||||
try {
|
||||
throw new NotValidBookException(errorMessage);
|
||||
} catch (Exception e) {
|
||||
assertEquals(NotValidBookException.class, e.getClass());
|
||||
assertEquals(errorMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,262 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
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.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BookRepositoryTest {
|
||||
|
||||
private BookRepository repository;
|
||||
private Book book1;
|
||||
private Book book2;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
repository = new BookRepository();
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
|
||||
book1 = Book.builder()
|
||||
.isbn("1234567890123")
|
||||
.title("Livre 1")
|
||||
.author("John Doe")
|
||||
.publisher("Editeur")
|
||||
.date(Date.from(Instant.now()))
|
||||
.price(5.99)
|
||||
.initialStock(50)
|
||||
.categories(categories)
|
||||
.description("Description")
|
||||
.language("Francais")
|
||||
.build();
|
||||
|
||||
book2 = Book.builder()
|
||||
.isbn("3210987654321")
|
||||
.title("Livre 2")
|
||||
.author("Jane Smith")
|
||||
.publisher("Editeur")
|
||||
.date(Date.from(Instant.now()))
|
||||
.price(8.54)
|
||||
.initialStock(42)
|
||||
.categories(categories)
|
||||
.description("Description")
|
||||
.language("Francais")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("New repository should be empty")
|
||||
void testNewRepositoryIsEmpty() {
|
||||
List<Book> books = repository.findAll();
|
||||
|
||||
assertTrue(books.isEmpty());
|
||||
assertEquals(0, books.size());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Save operations")
|
||||
class SaveOperations {
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should add a new book")
|
||||
void testSaveNewBook() {
|
||||
Book savedBook = repository.save(book1);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should update existing book with same ISBN")
|
||||
void testSaveUpdatesExistingBook() {
|
||||
repository.save(book1);
|
||||
|
||||
String isbn = book1.getIsbn();
|
||||
ArrayList<String> categories = book1.getCategories();
|
||||
Book updatedBook = Book.builder()
|
||||
.isbn(isbn)
|
||||
.title("Livre 1")
|
||||
.author("John Updated")
|
||||
.publisher("Editeur")
|
||||
.date(Date.from(Instant.now()))
|
||||
.price(4.99)
|
||||
.initialStock(42)
|
||||
.categories(categories)
|
||||
.description("Description")
|
||||
.language("Francais")
|
||||
.build();
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save multiple books should add all of them")
|
||||
void testSaveMultipleBooks() {
|
||||
repository.save(book1);
|
||||
repository.save(book2);
|
||||
|
||||
List<Book> books = repository.findAll();
|
||||
|
||||
assertEquals(2, books.size());
|
||||
assertTrue(books.contains(book1));
|
||||
assertTrue(books.contains(book2));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find operations")
|
||||
class FindOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpBooks() {
|
||||
repository.save(book1);
|
||||
repository.save(book2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindAll should return all books")
|
||||
void testFindAll() {
|
||||
List<Book> books = repository.findAll();
|
||||
|
||||
assertEquals(2, books.size());
|
||||
assertTrue(books.contains(book1));
|
||||
assertTrue(books.contains(book2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return book with matching ID")
|
||||
void testFindById() {
|
||||
Optional<Book> foundBook = repository.findByISBN(book1.getIsbn());
|
||||
|
||||
assertTrue(foundBook.isPresent());
|
||||
assertEquals(book1.getIsbn(), foundBook.get().getIsbn());
|
||||
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.getPrice(), foundBook.get().getPrice());
|
||||
assertEquals(book1.getInitialStock(), foundBook.get().getInitialStock());
|
||||
assertEquals(book1.getCategories(), foundBook.get().getCategories());
|
||||
assertEquals(book1.getDescription(), foundBook.get().getDescription());
|
||||
assertEquals(book1.getLanguage(), foundBook.get().getLanguage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return empty Optional when ID doesn't exist")
|
||||
void testFindByIdNotFound() {
|
||||
String nonExistentISBN = "1115553331112";
|
||||
|
||||
Optional<Book> foundBook = repository.findByISBN(nonExistentISBN);
|
||||
|
||||
assertTrue(foundBook.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByISBN should return book with matching ISBN")
|
||||
void testFindByISBN() {
|
||||
Optional<Book> foundBook = repository.findByISBN("1234567890123");
|
||||
|
||||
assertTrue(foundBook.isPresent());
|
||||
assertEquals(book1.getIsbn(), foundBook.get().getIsbn());
|
||||
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.getPrice(), foundBook.get().getPrice());
|
||||
assertEquals(book1.getInitialStock(), foundBook.get().getInitialStock());
|
||||
assertEquals(book1.getCategories(), foundBook.get().getCategories());
|
||||
assertEquals(book1.getDescription(), foundBook.get().getDescription());
|
||||
assertEquals(book1.getLanguage(), foundBook.get().getLanguage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByISBN should return empty Optional when ISBN doesn't exist")
|
||||
void testFindByISBNNotFound() {
|
||||
Optional<Book> foundBook = repository.findByISBN("0000000000000");
|
||||
|
||||
assertTrue(foundBook.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Delete operations")
|
||||
class DeleteOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpBooks() {
|
||||
repository.save(book1);
|
||||
repository.save(book2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Delete should remove the specified book")
|
||||
void testDelete() {
|
||||
repository.delete(book1);
|
||||
|
||||
List<Book> books = repository.findAll();
|
||||
|
||||
assertEquals(1, books.size());
|
||||
assertFalse(books.contains(book1));
|
||||
assertTrue(books.contains(book2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("DeleteAll should remove all books")
|
||||
void testDeleteAll() {
|
||||
repository.deleteAll();
|
||||
|
||||
List<Book> books = repository.findAll();
|
||||
|
||||
assertTrue(books.isEmpty());
|
||||
assertEquals(0, books.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Delete should not throw exception when book doesn't exist")
|
||||
void testDeleteNonExistentBook() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
Book nonExistentBook = Book.builder()
|
||||
.isbn("0000000000000")
|
||||
.title("Livre Non existant")
|
||||
.author("John Doe")
|
||||
.publisher("Editeur")
|
||||
.date(Date.from(Instant.now()))
|
||||
.price(5.99)
|
||||
.initialStock(50)
|
||||
.categories(categories)
|
||||
.description("Description")
|
||||
.language("Francais")
|
||||
.build();
|
||||
|
||||
assertDoesNotThrow(() -> repository.delete(nonExistentBook));
|
||||
|
||||
assertEquals(2, repository.findAll().size());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
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.entity.Book;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
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.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class BookUseCaseTest {
|
||||
|
||||
@Mock
|
||||
private BookRepository bookRepository;
|
||||
|
||||
@InjectMocks
|
||||
private BookUseCase bookUseCase;
|
||||
|
||||
private String bookISBN;
|
||||
private Book testBook;
|
||||
private BookInfo validBookInfo;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Histoire"); categories.add("Action");
|
||||
Date date = Date.from(Instant.now());
|
||||
testBook = Book.builder()
|
||||
.isbn(bookISBN)
|
||||
.title("LivreRandom")
|
||||
.author("John Doe")
|
||||
.publisher("RandomPublisher")
|
||||
.date(date)
|
||||
.price(12.5)
|
||||
.initialStock(50)
|
||||
.categories(categories)
|
||||
.description("Je suis un livre qui est composé de mots.")
|
||||
.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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Register Book Tests")
|
||||
public class RegisterBookTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should register book when valid data is provided")
|
||||
void testRegisterBookWithValidData() throws NotValidBookException {
|
||||
when(bookRepository.save(any(Book.class))).thenReturn(testBook);
|
||||
|
||||
String registeredISBN = bookUseCase.registerBook(validBookInfo);
|
||||
|
||||
assertNotNull(registeredISBN);
|
||||
assertEquals(bookISBN, registeredISBN);
|
||||
verify(bookRepository, times(1)).save(any(Book.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when book data is not valid")
|
||||
void testRegisterBookWithInvalidData() {
|
||||
BookInfo invalidBookInfo = new BookInfo("", "", "", "", Date.from(Instant.now()),-78, -1, null, "", "");
|
||||
|
||||
assertThrows(NotValidBookException.class,
|
||||
() -> bookUseCase.registerBook(invalidBookInfo));
|
||||
|
||||
verify(bookRepository, never()).save(any(Book.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find book tests")
|
||||
class FindBookTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return book when ISBN exists")
|
||||
void testFindBookByISBN() {
|
||||
when(bookRepository.findByISBN("1234567890123")).thenReturn(Optional.empty());
|
||||
|
||||
Optional<BookDTO> foundBook = bookUseCase.findBookByISBN("1234567890123");
|
||||
|
||||
assertTrue(foundBook.isPresent());
|
||||
assertEquals(testBook.getIsbn(), foundBook.get().getIsbn());
|
||||
assertEquals(testBook.getTitle(), foundBook.get().getTitle());
|
||||
verify(bookRepository, times(1)).findByISBN("1234567890123");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return empty Optional when ISBN doesn't exist")
|
||||
void testFindBookByISBNNotFound() {
|
||||
when(bookRepository.findByISBN("9999999999999")).thenReturn(Optional.empty());
|
||||
|
||||
Optional<BookDTO> foundBook = bookUseCase.findBookByISBN("9999999999999");
|
||||
|
||||
assertTrue(foundBook.isEmpty());
|
||||
verify(bookRepository, times(1)).findByISBN("9999999999999");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Delete book tests")
|
||||
class DeleteBookTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should delete book when ISBN exists")
|
||||
void testDeleteBook() throws BookNotFoundException {
|
||||
when(bookRepository.findByISBN(bookISBN)).thenReturn(Optional.of(testBook));
|
||||
doNothing().when(bookRepository).delete(testBook);
|
||||
|
||||
bookUseCase.deleteBook(bookISBN);
|
||||
|
||||
verify(bookRepository, times(1)).findByISBN(bookISBN);
|
||||
verify(bookRepository, times(1)).delete(testBook);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when book ISBN doesn't exist")
|
||||
void testDeleteBookNotFound() {
|
||||
String nonExistentISBN = "0000000000001";
|
||||
when(bookRepository.findByISBN(nonExistentISBN)).thenReturn(Optional.empty());
|
||||
|
||||
assertThrows(BookNotFoundException.class,
|
||||
() -> bookUseCase.deleteBook(nonExistentISBN));
|
||||
|
||||
verify(bookRepository, times(1)).findByISBN(nonExistentISBN);
|
||||
verify(bookRepository, never()).delete(any(Book.class));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,244 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.book.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.NotValidCustomerException;
|
||||
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.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BookValidatorTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should validate book with valid data")
|
||||
void testValidateValidBook() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo validBook = new BookInfo("1234567891234", "Livre", "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
assertDoesNotThrow(() -> BookValidator.validate(validBook));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("ISBN validation tests")
|
||||
class ISBNValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when ISBN is blank")
|
||||
void testValidateBlankISBN() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankISBN = new BookInfo("", "Livre", "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankISBN)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.ISBN_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when ISBN contains only whitespace")
|
||||
void testValidateWhitespaceISBN(String whitespace) {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithWhitespaceISBN = new BookInfo(whitespace, "Livre", "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithWhitespaceISBN)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.ISBN_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"hfoahdiehfyui", "123456789 0123", "123", "12345678901234","123456789 123"})
|
||||
@DisplayName("Should throw exception when ISBN is not a valid format")
|
||||
void testValidateNotValidISBN(String testedISBN) {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithInvalidISBN = new BookInfo(testedISBN, "Livre", "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithInvalidISBN)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.ISBN_IS_NOT_VALID, exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Title validation tests")
|
||||
class TitleValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Title is blank")
|
||||
void testValidateBlankTitle() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankTitle = new BookInfo("1234567890123", "", "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankTitle)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.TITLE_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when Title contains only whitespace")
|
||||
void testValidateWhitespaceTitle(String whitespace) {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankTitle = new BookInfo("1234567890123", whitespace, "john doe","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankTitle)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.TITLE_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Author validation tests")
|
||||
class AuthorValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Author is blank")
|
||||
void testValidateBlankAuthor() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankAuthor = new BookInfo("1234567890123", "Livre", "","editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankAuthor)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.AUTHOR_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when Author contains only whitespace")
|
||||
void testValidateWhitespaceAuthor(String whitespace) {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankAuthor = new BookInfo("1234567890123", "Livre", whitespace,"editeur", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankAuthor)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.AUTHOR_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Publisher validation tests")
|
||||
class PublisherValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Publisher is blank")
|
||||
void testValidateBlankPublisher() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankPublisher = new BookInfo("1234567890123", "Livre", "Auteur","", Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankPublisher)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.PUBLISHER_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when Publisher contains only whitespace")
|
||||
void testValidateWhitespacePublisher(String whitespace) {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithBlankPublisher = new BookInfo("1234567890123", "Livre", "Auteur",whitespace, Date.from(Instant.now()),5.99,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithBlankPublisher)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.PUBLISHER_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
@DisplayName("Price validation tests")
|
||||
class PriceValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Price is negative")
|
||||
void testValidateNegativePrice() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithNegativePrice = new BookInfo("1234567890123", "Livre", "Auteur","Editeur", Date.from(Instant.now()),-4.98,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithNegativePrice)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.PRICE_CANNOT_BE_NEGATIVE, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Price is equal to zero")
|
||||
void testValidatePriceEqualToZero() {
|
||||
ArrayList<String> categories = new ArrayList<>(); categories.add("Categorie1"); categories.add("Categorie2");
|
||||
BookInfo bookWithPriceEqualToZero = new BookInfo("1234567890123", "Livre", "Auteur","Editeur", Date.from(Instant.now()),0,15,categories,"description","langue");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithPriceEqualToZero)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.PRICE_CANNOT_BE_EQUAL_TO_ZERO, exception.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Initial Stock validation tests")
|
||||
class InitialStockValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when Initial Stock is negative")
|
||||
void testValidateNegativePrice() {
|
||||
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");
|
||||
|
||||
NotValidBookException exception = assertThrows(
|
||||
NotValidBookException.class,
|
||||
() -> BookValidator.validate(bookWithNegativeInitialStock)
|
||||
);
|
||||
|
||||
assertEquals(BookValidator.INITIAL_STOCK_CANNOT_BE_NEGATIVE, exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -220,4 +220,5 @@ public class CustomerSteps {
|
||||
assertEquals(errorMessage, illegalCustomerPointException.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,222 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.features.livre;
|
||||
|
||||
|
||||
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.BookDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
|
||||
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.BookNotFoundExceptionTest;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.usecase.BookUseCase;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.NotValidCustomerException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.usecase.CustomerUseCase;
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.ParameterType;
|
||||
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.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class BookSteps {
|
||||
|
||||
private final Map<String, String> bookISBN = new HashMap<>();
|
||||
private final BookRepository bookRepository = new BookRepository();
|
||||
private final BookUseCase bookUseCase = new BookUseCase(bookRepository);
|
||||
private String bookRegistration;
|
||||
private Book updatedBook;
|
||||
private Optional<BookDTO> bookByISBN;
|
||||
private NotValidBookException notValidBookException;
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH);
|
||||
|
||||
private ArrayList<String> listOfStrings(String arg) {
|
||||
return new ArrayList<String>(Arrays.asList(arg.split(",\\s")));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Given("le systeme possedent les livres suivants :")
|
||||
public void theSystemHasTheFollowingBooks(DataTable dataTable) throws ParseException {
|
||||
int size = bookRepository.findAll().size();
|
||||
|
||||
if (size > 0) {
|
||||
bookRepository.deleteAll();
|
||||
}
|
||||
|
||||
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"))
|
||||
.date(formatter.parse(book.get("datePublication")))
|
||||
.price(Double.parseDouble(book.get("prix")))
|
||||
.initialStock(Integer.parseInt(book.get("stockInitial")))
|
||||
.categories(listOfStrings(book.get("categories")))
|
||||
.description(book.get("description"))
|
||||
.language(book.get("langue"))
|
||||
.build();
|
||||
Book save = bookRepository.save(newBook);
|
||||
bookISBN.put(ISBN, save.getIsbn());
|
||||
}
|
||||
|
||||
assertEquals(books.size(), bookRepository.findAll().size());
|
||||
}
|
||||
|
||||
@When("Je cree un nouveau livre avec les informations suivantes :")
|
||||
public void iCreateANewBookWithTheFollowingInformation(DataTable dataTable) throws NotValidBookException, ParseException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
Map<String, String> bookInfo = rows.getFirst();
|
||||
|
||||
|
||||
BookInfo newBook = new BookInfo(
|
||||
bookInfo.get("ISBN"),
|
||||
bookInfo.get("titre"),
|
||||
bookInfo.get("auteur"),
|
||||
bookInfo.get("editeur"),
|
||||
formatter.parse(bookInfo.get("datePublication")),
|
||||
Double.parseDouble(bookInfo.get("prix")),
|
||||
Integer.parseInt(bookInfo.get("stockInitial")),
|
||||
listOfStrings(bookInfo.get("categories")),
|
||||
bookInfo.get("description"),
|
||||
bookInfo.get("langue")
|
||||
);
|
||||
|
||||
bookRegistration = bookUseCase.registerBook(newBook);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Then("Un nouveau livre est cree")
|
||||
public void aNewBookIsCreated(){
|
||||
assertNotNull(bookRegistration);
|
||||
}
|
||||
|
||||
@When("Je modifie le livre avec l'ISBN {string} avec les informations suivantes:")
|
||||
public void iUpdateABookWithTheFollowingInformation(String isbn, DataTable dataTable) throws BookNotFoundException, NotValidBookException, ParseException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
Map<String, String> bookData = rows.getFirst();
|
||||
BookInfo bookInfo = new BookInfo(
|
||||
bookData.get("ISBN"),
|
||||
bookData.get("titre"),
|
||||
bookData.get("auteur"),
|
||||
bookData.get("editeur"),
|
||||
formatter.parse(bookData.get("datePublication")),
|
||||
Double.parseDouble(bookData.get("prix")),
|
||||
Integer.parseInt(bookData.get("stockInitial")),
|
||||
listOfStrings(bookData.get("categories")),
|
||||
bookData.get("description"),
|
||||
bookData.get("langue")
|
||||
);
|
||||
bookUseCase.updateBook(isbn, bookInfo);
|
||||
|
||||
}
|
||||
|
||||
@Then("Le livre {string} a les informations suivantes:")
|
||||
public void theBookHasFollowingInformations(String isbn, DataTable dataTable) throws ParseException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
Map<String, String> updatedData = rows.getFirst();
|
||||
|
||||
|
||||
updatedBook = bookRepository.findByISBN(isbn).orElseThrow();
|
||||
assertEquals(updatedData.get("ISBN"), updatedBook.getIsbn());
|
||||
assertEquals(updatedData.get("titre"), updatedBook.getTitle());
|
||||
assertEquals(updatedData.get("auteur"), updatedBook.getAuthor());
|
||||
assertEquals(updatedData.get("editeur"), updatedBook.getPublisher());
|
||||
assertEquals(formatter.parse(updatedData.get("datePublication")), updatedBook.getDate());
|
||||
assertEquals(Double.parseDouble(updatedData.get("prix")), updatedBook.getPrice());
|
||||
assertEquals(Integer.parseInt(updatedData.get("stockInitial")), updatedBook.getInitialStock());
|
||||
assertEquals(listOfStrings(updatedData.get("categories")), updatedBook.getCategories());
|
||||
assertEquals(updatedData.get("description"), updatedBook.getDescription());
|
||||
assertEquals(updatedData.get("langue"), updatedBook.getLanguage());
|
||||
}
|
||||
|
||||
@When("Je supprime le livre avec l'ISBN {string}")
|
||||
public void iDeleteTheFollowingBook(String isbn) throws BookNotFoundException {
|
||||
bookUseCase.deleteBook(isbn);
|
||||
}
|
||||
|
||||
@Then("Le livre {string} n'existe plus dans le systeme")
|
||||
public void theBookDoesNotExistInTheSystem(String isbn){
|
||||
assertFalse(bookRepository.existsByISBN(isbn));
|
||||
}
|
||||
|
||||
@And("Le systeme contient {int} livre")
|
||||
public void theSystemContainsThisMuchBooks(int nBooks){
|
||||
assertEquals(nBooks,bookRepository.findAll().size());
|
||||
}
|
||||
|
||||
@When("Je demande les informations du lirve avec l'ISBN {string}")
|
||||
public void iAskForTheBookWithISBN(String isbn){
|
||||
bookByISBN = bookUseCase.findBookByISBN(isbn);
|
||||
}
|
||||
|
||||
@Then("Je recupere les informations suivantes:")
|
||||
public void iGetTheFollowingInformation(DataTable dataTable) throws ParseException {
|
||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||
Map<String, String> bookInfo = books.getFirst();
|
||||
assertTrue(bookByISBN.isPresent());
|
||||
BookDTO bookDTO = bookByISBN.get();
|
||||
assertEquals(bookInfo.get("ISBN"), bookDTO.getIsbn());
|
||||
assertEquals(bookInfo.get("titre"), bookDTO.getTitle());
|
||||
assertEquals(bookInfo.get("auteur"), bookDTO.getAuthor());
|
||||
assertEquals(bookInfo.get("editeur"), bookDTO.getPublisher());
|
||||
assertEquals(formatter.parse(bookInfo.get("datePublication")), bookDTO.getDate());
|
||||
assertEquals(Double.parseDouble(bookInfo.get("prix")), bookDTO.getPrice());
|
||||
assertEquals(Integer.parseInt(bookInfo.get("stockInitial")), bookDTO.getInitialStock());
|
||||
assertEquals(listOfStrings(bookInfo.get("categories")), bookDTO.getCategories());
|
||||
assertEquals(bookInfo.get("description"), bookDTO.getDescription());
|
||||
assertEquals(bookInfo.get("langue"), bookDTO.getLanguage());
|
||||
}
|
||||
|
||||
@When("J'essaie de creer un nouveau livre avec les informations suivantes :")
|
||||
public void iTryToCreateANewBookWithFollowingInformation(DataTable dataTable) throws ParseException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
Map<String, String> bookInfo = rows.getFirst();
|
||||
|
||||
BookInfo newBook = new BookInfo(
|
||||
bookInfo.get("ISBN"),
|
||||
bookInfo.get("titre"),
|
||||
bookInfo.get("auteur"),
|
||||
bookInfo.get("editeur"),
|
||||
formatter.parse(bookInfo.get("datePublication")),
|
||||
Double.parseDouble(bookInfo.get("prix")),
|
||||
Integer.parseInt(bookInfo.get("stockInitial")),
|
||||
listOfStrings(bookInfo.get("categories")),
|
||||
bookInfo.get("description"),
|
||||
bookInfo.get("langue")
|
||||
);
|
||||
|
||||
notValidBookException = assertThrows(NotValidBookException.class, () -> bookUseCase.registerBook(newBook));
|
||||
}
|
||||
|
||||
@Then("La creation echoue")
|
||||
public void creationFailed(){
|
||||
assertNotNull(notValidBookException);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,250 @@
|
||||
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.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.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
|
||||
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.*;
|
||||
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 ArrayList<String> listOfStrings(String arg) {
|
||||
return new ArrayList<String>(Arrays.asList(arg.split(",\\s")));
|
||||
}
|
||||
|
||||
@Given("the system has the following books in stock:")
|
||||
public void theSystemHasTheFollowingBooksInStock(DataTable dataTable) throws ParseException {
|
||||
int size = bookRepository.findAll().size();
|
||||
|
||||
if (size > 0) {
|
||||
bookRepository.deleteAll();
|
||||
}
|
||||
|
||||
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"))
|
||||
.date(formatter.parse(book.get("datePublication")))
|
||||
.price(Double.parseDouble(book.get("prix")))
|
||||
.initialStock(Integer.parseInt(book.get("stockInitial")))
|
||||
.categories(listOfStrings(book.get("categories")))
|
||||
.description(book.get("description"))
|
||||
.language(book.get("langue"))
|
||||
.build();
|
||||
Book save = bookRepository.save(newBook);
|
||||
BookISBN.put(ISBN, save.getIsbn());
|
||||
}
|
||||
|
||||
assertEquals(books.size(), bookRepository.findAll().size());
|
||||
}
|
||||
|
||||
@Given("the system has the following customers:")
|
||||
public void theSystemHasTheFollowingCustomers(DataTable dataTable) {
|
||||
int size = customerRepository.findAll().size();
|
||||
|
||||
if (size > 0) {
|
||||
customerRepository.deleteAll();
|
||||
}
|
||||
|
||||
List<Map<String, String>> customers = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
for (Map<String, String> customer : customers) {
|
||||
String numeroTelephone = customer.get("numeroTelephone");
|
||||
Customer newCustomer = Customer.builder()
|
||||
.firstName(customer.get("prenom"))
|
||||
.lastName(customer.get("nom"))
|
||||
.phoneNumber(numeroTelephone)
|
||||
.loyaltyPoints(Integer.parseInt(customer.get("pointsFidelite")))
|
||||
.build();
|
||||
Customer save = customerRepository.save(newCustomer);
|
||||
customerPhoneUUID.put(numeroTelephone, save.getId());
|
||||
}
|
||||
|
||||
assertEquals(customers.size(), customerRepository.findAll().size());
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@And("the order includes the following books:")
|
||||
public void theOrderIncludesTheFollowingBooks(DataTable dataTable) {
|
||||
List<Map<String, String>> books = dataTable.asMaps(String.class, String.class);
|
||||
for (Map<String, String> book : books) {
|
||||
String isbn = book.get("isbn");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@And("the total price is {double}")
|
||||
public void theTotalPriceIs(double price) {
|
||||
Order order = orderRepository.findById(orderRegistration);
|
||||
assertEquals(price, order.getTotalPrice());
|
||||
}
|
||||
|
||||
@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("{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() {
|
||||
|
||||
}
|
||||
|
||||
@And("I receive an error for not found exception message containing {string}")
|
||||
public void iReceiveAnErrorForNotFoundExceptionMessageContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, orderNotFoundException.getMessage());
|
||||
}
|
||||
|
||||
@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}")
|
||||
public void iReceiveAnErrorForIllegalOrderExceptionMessageContaining(String errorMessage) {
|
||||
assertEquals(errorMessage, illegalOrderPointException.getMessage());
|
||||
}
|
||||
|
||||
@When("I create a new order with an invalid payment method:")
|
||||
public void iCreateANewOrderWithAnInvalidPaymentMethod() {
|
||||
}
|
||||
|
||||
@And("the order includes no books")
|
||||
public void theOrderIncludesNoBooks() {
|
||||
}
|
||||
|
||||
@Given("an order with ID {string} exists for customer {string}")
|
||||
public void anOrderWithIDExistsForCustomer(String arg0, String arg1) {
|
||||
}
|
||||
|
||||
@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() {
|
||||
}
|
||||
|
||||
@Then("I receive the order details")
|
||||
public void iReceiveTheOrderDetails() {
|
||||
}
|
||||
|
||||
@Then("I receive a list of orders")
|
||||
public void iReceiveAListOfOrders() {
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.features.subscription;
|
||||
|
||||
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.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.entity.Subscription;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException;
|
||||
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;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
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.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class SubscriptionSteps {
|
||||
|
||||
private final SubscriptionRepository subscriptionRepository = new SubscriptionRepository();
|
||||
private final SubscriptionUseCase subscriptionUseCase = new SubscriptionUseCase(subscriptionRepository);
|
||||
private NotValidSubscriptionException notValidSubscriptionException;
|
||||
|
||||
private final CustomerRepository customerRepository = new CustomerRepository();
|
||||
private UUID subscriptionRegistration;
|
||||
private final Map<String, UUID> customerPhoneUUID = new HashMap<>();
|
||||
|
||||
@Given("the system has the following customers:")
|
||||
public void theSystemHasTheFollowingCustomers(DataTable dataTable) {
|
||||
int size = customerRepository.findAll().size();
|
||||
|
||||
if (size > 0) {
|
||||
customerRepository.deleteAll();
|
||||
}
|
||||
|
||||
List<Map<String, String>> customers = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
for (Map<String, String> customer : customers) {
|
||||
String numeroTelephone = customer.get("numeroTelephone");
|
||||
Customer newCustomer = Customer.builder()
|
||||
.firstName(customer.get("prenom"))
|
||||
.lastName(customer.get("nom"))
|
||||
.phoneNumber(numeroTelephone)
|
||||
.loyaltyPoints(Integer.parseInt(customer.get("pointsFidelite")))
|
||||
.build();
|
||||
Customer save = customerRepository.save(newCustomer);
|
||||
customerPhoneUUID.put(numeroTelephone, save.getId());
|
||||
}
|
||||
|
||||
assertEquals(customers.size(), customerRepository.findAll().size());
|
||||
}
|
||||
|
||||
@When("I create a new subscription with CB:")
|
||||
public void iCreateANewSubscriptionWithCB(DataTable dataTable) throws NotValidSubscriptionException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
// Extract the first row of data
|
||||
Map<String, String> subscriptionData = rows.getFirst();
|
||||
|
||||
// Create a new SubscriptionInfo object with the correct keys
|
||||
SubscriptionInfo newSubscription = new SubscriptionInfo(
|
||||
UUID.fromString(subscriptionData.get("customerId")),
|
||||
Integer.parseInt(subscriptionData.get("duration")),
|
||||
subscriptionData.get("paymentMethod")
|
||||
);
|
||||
|
||||
// Register the subscription
|
||||
subscriptionRegistration = subscriptionUseCase.registerSubscription(newSubscription);
|
||||
}
|
||||
|
||||
@Then("a new subscription is created")
|
||||
public void aNewSubscriptionIsCreated() {
|
||||
|
||||
}
|
||||
|
||||
@When("I create a new subscription with Paypal:")
|
||||
public void iCreateANewSubscriptionWithPaypal(DataTable dataTable) throws NotValidSubscriptionException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
// Extract the first row of data
|
||||
Map<String, String> subscriptionData = rows.getFirst();
|
||||
|
||||
// Create a new SubscriptionInfo object with the correct keys
|
||||
SubscriptionInfo newSubscription = new SubscriptionInfo(
|
||||
UUID.fromString(subscriptionData.get("customerId")),
|
||||
Integer.parseInt(subscriptionData.get("duration")),
|
||||
subscriptionData.get("paymentMethod")
|
||||
);
|
||||
|
||||
// Register the subscription
|
||||
subscriptionRegistration = subscriptionUseCase.registerSubscription(newSubscription);
|
||||
}
|
||||
|
||||
@When("I try to create a new subscription with the following information:")
|
||||
public void iTryToCreateANewSubscriptionWithTheFollowingInformation(DataTable dataTable) throws NotValidSubscriptionException {
|
||||
List<Map<String, String>> rows = dataTable.asMaps(String.class, String.class);
|
||||
|
||||
Map<String, String> subscriptionData = rows.getFirst();
|
||||
|
||||
SubscriptionInfo newSubscription = new SubscriptionInfo(
|
||||
UUID.fromString(subscriptionData.get("customerId")),
|
||||
Integer.parseInt(subscriptionData.get("duration")),
|
||||
subscriptionData.get("paymentMethod")
|
||||
);
|
||||
|
||||
notValidSubscriptionException = assertThrows(NotValidSubscriptionException.class, () -> subscriptionUseCase.registerSubscription(newSubscription));
|
||||
}
|
||||
|
||||
@Then("the subsription duration creation fails")
|
||||
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());
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.converter;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.CustomerInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.converter.CustomerConverter;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
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 java.util.UUID;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
@DisplayName("SubscriptionConverter Unit Tests")
|
||||
public class SubscriptionConverterTest {
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDomain() method tests")
|
||||
public class toDomainTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert SubscriptionInfo to Subscription domain object")
|
||||
void shouldConvertSubscriptionInfoToDomain() {
|
||||
// Given
|
||||
SubscriptionInfo subscriptionInfo = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), 12, "CB");
|
||||
|
||||
// When
|
||||
Subscription result = SubscriptionConverter.toDomain(subscriptionInfo);
|
||||
|
||||
// Then
|
||||
assertNotNull(result);
|
||||
assertEquals(subscriptionInfo.customerId(), result.getCustomerId());
|
||||
assertEquals(subscriptionInfo.duration(), result.getDuration());
|
||||
assertEquals(subscriptionInfo.paymentMethod(), result.getPaymentMethod());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDTO() method tests")
|
||||
public class toDTOTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert Subscriber domain object to SubscriberDTO with all fields mapped correctly")
|
||||
void shouldConvertSubscriptionToDTO() {
|
||||
UUID id = UUID.randomUUID();
|
||||
|
||||
Subscription subscription = Subscription.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.customerId(id)
|
||||
.duration(12)
|
||||
.paymentMethod("CB")
|
||||
.debutDate("2025-06-08")
|
||||
.build();
|
||||
|
||||
SubscriptionDTO result = SubscriptionConverter.toDTO(subscription);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(subscription.getId(), result.getId());
|
||||
assertEquals(subscription.getCustomerId(), result.getCustomerId());
|
||||
assertEquals(subscription.getDuration(), result.getDuration());
|
||||
assertEquals(subscription.getPaymentMethod(), result.getPaymentMethod());
|
||||
assertEquals(subscription.getDebutDate(), result.getDebutDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should handle null values properly when converting between objects")
|
||||
void shouldHandleNullValuesGracefully() {
|
||||
Subscription subscription = Subscription.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.customerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"))
|
||||
.duration(null)
|
||||
.paymentMethod("NullTest")
|
||||
.debutDate("2025-06-08")
|
||||
.build();
|
||||
|
||||
SubscriptionDTO result = SubscriptionConverter.toDTO(subscription);
|
||||
|
||||
assertNotNull(result);
|
||||
assertNull(result.getDuration());
|
||||
assertEquals("NullTest", result.getPaymentMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should preserve empty string values during conversion")
|
||||
void shouldPreserveEmptyStrings() {
|
||||
SubscriptionInfo subscriptionInfo = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), 12, "");
|
||||
|
||||
Subscription domainResult = SubscriptionConverter.toDomain(subscriptionInfo);
|
||||
SubscriptionDTO dtoResult = SubscriptionConverter.toDTO(domainResult);
|
||||
|
||||
assertEquals("", dtoResult.getPaymentMethod());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,49 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class SubscriptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Builder should create a valid Subscription instance")
|
||||
void testSubscriptionBuilder() {
|
||||
UUID id = UUID.randomUUID();
|
||||
UUID customerId = UUID.fromString("123e4567-e89b-12d3-a456-426614174000");
|
||||
int duration = 12;
|
||||
String paymentMethod = "CB";
|
||||
String debutDate = "2025-06-08";
|
||||
|
||||
Subscription subscription = Subscription.builder()
|
||||
.id(id)
|
||||
.customerId(customerId)
|
||||
.duration(duration)
|
||||
.paymentMethod(paymentMethod)
|
||||
.debutDate(debutDate)
|
||||
.build();
|
||||
|
||||
assertEquals(id, subscription.getId());
|
||||
assertEquals(customerId, subscription.getCustomerId());
|
||||
assertEquals(duration, subscription.getDuration());
|
||||
assertEquals(paymentMethod, subscription.getPaymentMethod());
|
||||
assertEquals(debutDate, subscription.getDebutDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("setRandomUUID should change the ID to a new random UUID")
|
||||
void testSetRandomUUID() {
|
||||
Subscription subscription = Subscription.builder().build();
|
||||
UUID originalId = subscription.getId();
|
||||
|
||||
subscription.setRandomUUID();
|
||||
|
||||
assertNotNull(subscription.getId());
|
||||
assertNotEquals(originalId, subscription.getId());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,155 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity.Subscription;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.repository.SubscriptionRepository;
|
||||
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.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class SubscriptionRepositoryTest {
|
||||
|
||||
|
||||
private SubscriptionRepository repository;
|
||||
private Subscription Subscription1;
|
||||
private Subscription Subscription2;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
repository = new SubscriptionRepository();
|
||||
|
||||
Subscription1 = Subscription.builder()
|
||||
.customerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"))
|
||||
.duration(12)
|
||||
.paymentMethod("CB")
|
||||
.build();
|
||||
Subscription1.setRandomUUID();
|
||||
|
||||
Subscription2 = Subscription.builder()
|
||||
.customerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"))
|
||||
.duration(24)
|
||||
.paymentMethod("Paypal")
|
||||
.build();
|
||||
Subscription2.setRandomUUID();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("New repository should be empty")
|
||||
void testNewRepositoryIsEmpty() {
|
||||
List<Subscription> subscriptions = repository.findAll();
|
||||
|
||||
assertTrue(subscriptions.isEmpty());
|
||||
assertEquals(0, subscriptions.size());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Save operations")
|
||||
class SaveOperations {
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should add a new subsciption")
|
||||
void testSaveNewSubscription() {
|
||||
Subscription savedSubscription = repository.save(Subscription1);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertEquals(Subscription1.getId(), savedSubscription.getId());
|
||||
assertEquals(Subscription1.getDebutDate(), savedSubscription.getDebutDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save multiple Subscriptions should add all of them")
|
||||
void testSaveMultipleSubscriptions() {
|
||||
repository.save(Subscription1);
|
||||
repository.save(Subscription2);
|
||||
|
||||
List<Subscription> subscriptions = repository.findAll();
|
||||
|
||||
assertEquals(2, subscriptions.size());
|
||||
assertTrue(subscriptions.contains(Subscription1));
|
||||
assertTrue(subscriptions.contains(Subscription2));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find operations")
|
||||
class FindOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpSubscriptions() {
|
||||
repository.save(Subscription1);
|
||||
repository.save(Subscription2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindAll should return all subscriptions")
|
||||
void testFindAll() {
|
||||
List<Subscription> subscriptions = repository.findAll();
|
||||
|
||||
assertEquals(2, subscriptions.size());
|
||||
assertTrue(subscriptions.contains(Subscription1));
|
||||
assertTrue(subscriptions.contains(Subscription2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return subscriptions with matching ID")
|
||||
void testFindById() {
|
||||
Optional<Subscription> foundSubscription = repository.findByCustomerId(Subscription1.getId());
|
||||
|
||||
assertTrue(foundSubscription.isPresent());
|
||||
assertEquals(Subscription1.getId(), foundSubscription.get().getId());
|
||||
assertEquals(Subscription1.getCustomerId(), foundSubscription.get().getCustomerId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return empty Optional when ID doesn't exist")
|
||||
void testFindByIdNotFound() {
|
||||
UUID nonExistentId = UUID.randomUUID();
|
||||
|
||||
Optional<Subscription> foundSubscription = repository.findByCustomerId(nonExistentId);
|
||||
|
||||
assertTrue(foundSubscription.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByCustomerId should return customer with matching customer id")
|
||||
void testFindByCustomerId() {
|
||||
Optional<Subscription> foundSubscription = repository.findByCustomerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"));
|
||||
|
||||
assertTrue(foundSubscription.isPresent());
|
||||
assertEquals(Subscription1.getId(), foundSubscription.get().getId());
|
||||
assertEquals(Subscription1.getDebutDate(), foundSubscription.get().getDebutDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByCustomerId should return empty Optional when phone number doesn't exist")
|
||||
void testFindByPhoneNumberNotFound() {
|
||||
Optional<Subscription> foundSubscription = repository.findByCustomerId(UUID.fromString("0000000-0000-0000-0000-000000000000"));
|
||||
|
||||
assertTrue(foundSubscription.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ExistsById should return true when ID exists")
|
||||
void testExistsByIdExists() {
|
||||
boolean exists = repository.existsById(Subscription1.getId());
|
||||
|
||||
assertTrue(exists);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ExistsById should return false when ID doesn't exist")
|
||||
void testExistsByIdNotExists() {
|
||||
UUID nonExistentId = UUID.randomUUID();
|
||||
|
||||
boolean exists = repository.existsById(nonExistentId);
|
||||
|
||||
assertFalse(exists);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.entity.Subscription;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.SubscriptionNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.repository.SubscriptionRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.usecase.SubscriptionUseCase;
|
||||
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.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class SubscribeUseCaseTest {
|
||||
|
||||
@Mock
|
||||
private SubscriptionRepository subscriptionRepository;
|
||||
|
||||
@InjectMocks
|
||||
private SubscriptionUseCase subscriptionUseCase;
|
||||
|
||||
private UUID subscriptionId;
|
||||
private Subscription testSubscription;
|
||||
private SubscriptionInfo validSubscriptionInfo;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
subscriptionId = UUID.randomUUID();
|
||||
testSubscription = Subscription.builder()
|
||||
.id(subscriptionId)
|
||||
.customerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"))
|
||||
.duration(12)
|
||||
.paymentMethod("CB")
|
||||
.build();
|
||||
|
||||
validSubscriptionInfo = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), 12, "CB");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Register subscription tests")
|
||||
class RegisterSubscriptionTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should register subscription when valid data is provided")
|
||||
void testRegisterSubscriptionWithValidData() throws NotValidSubscriptionException {
|
||||
when(subscriptionRepository.save(any(Subscription.class))).thenReturn(testSubscription);
|
||||
|
||||
UUID registeredId = subscriptionUseCase.registerSubscription(validSubscriptionInfo);
|
||||
|
||||
assertNotNull(registeredId);
|
||||
assertEquals(subscriptionId, registeredId);
|
||||
verify(subscriptionRepository, times(1)).save(any(Subscription.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when subscription data is not valid")
|
||||
void testRegisterSubscriptionWithInvalidData() {
|
||||
SubscriptionInfo invalidSubscriptionInfo = new SubscriptionInfo(null, null, "");
|
||||
|
||||
assertThrows(NotValidSubscriptionException.class,
|
||||
() -> subscriptionUseCase.registerSubscription(invalidSubscriptionInfo));
|
||||
|
||||
verify(subscriptionRepository, never()).save(any(Subscription.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find subscription tests")
|
||||
class FindSubscriptionTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return subscription when phone number exists")
|
||||
void testFindSubscriptionByCustomerId() {
|
||||
when(subscriptionRepository.findByCustomerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"))).thenReturn(Optional.of(testSubscription));
|
||||
|
||||
Optional<SubscriptionDTO> foundSubscription = subscriptionUseCase.findSubscriptionByCustomerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"));
|
||||
|
||||
assertTrue(foundSubscription.isPresent());
|
||||
assertEquals(testSubscription.getId(), foundSubscription.get().getId());
|
||||
assertEquals(testSubscription.getDebutDate(), foundSubscription.get().getDebutDate());
|
||||
verify(subscriptionRepository, times(1)).findByCustomerId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return empty Optional when phone number doesn't exist")
|
||||
void testFindSubscriptionByPhoneNumberNotFound() {
|
||||
when(subscriptionRepository.findByCustomerId(UUID.fromString("0000000-0000-0000-0000-000000000000"))).thenReturn(Optional.empty());
|
||||
|
||||
Optional<SubscriptionDTO> foundSubscription = subscriptionUseCase.findSubscriptionByCustomerId(UUID.fromString("0000000-0000-0000-0000-000000000000"));
|
||||
|
||||
assertTrue(foundSubscription.isEmpty());
|
||||
verify(subscriptionRepository, times(1)).findByCustomerId(UUID.fromString("0000000-0000-0000-0000-000000000000"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,121 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.subscription.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.SubscriptionInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.subscription.exception.NotValidSubscriptionException;
|
||||
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.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class SubscriptionValidatorTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should validate subscription with valid data")
|
||||
void testValidateValidSubscription() {
|
||||
SubscriptionInfo validSubscription = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), 12, "CB");
|
||||
|
||||
assertDoesNotThrow(() -> SubscriptionValidator.validate(validSubscription));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("customer id validation tests")
|
||||
class CustomerIdValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when customer id is blank")
|
||||
void testValidateBlankCustomerId() {
|
||||
SubscriptionInfo subscriptionWithBlankCustomerId = new SubscriptionInfo(null, 12, "CB");
|
||||
|
||||
NotValidSubscriptionException exception = assertThrows(
|
||||
NotValidSubscriptionException.class,
|
||||
() -> SubscriptionValidator.validate(subscriptionWithBlankCustomerId)
|
||||
);
|
||||
|
||||
assertEquals(SubscriptionValidator.CUSTOMER_ID_CANNOT_BE_NULL,
|
||||
exception.getMessage());
|
||||
}
|
||||
|
||||
/**@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when customer id contains only whitespace")
|
||||
void testValidateWhitespaceCustomerId(String whitespace) {
|
||||
SubscriptionInfo subscriptionWithWhitespaceFirstName = new SubscriptionInfo(whitespace, 12, "CB");
|
||||
|
||||
NotValidSubscriptionException exception = assertThrows(
|
||||
NotValidSubscriptionException.class,
|
||||
() -> SubscriptionValidator.validate(subscriptionWithWhitespaceCustomerId)
|
||||
);
|
||||
|
||||
assertEquals(SubscriptionValidator.CUSTOMER_ID_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}**/
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Duration validation tests")
|
||||
class DurationValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when duration is blank")
|
||||
void testValidateBlankDuration() {
|
||||
SubscriptionInfo subscriptionWithBlankDuration = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), null, "CB");
|
||||
|
||||
NotValidSubscriptionException exception = assertThrows(
|
||||
NotValidSubscriptionException.class,
|
||||
() -> SubscriptionValidator.validate(subscriptionWithBlankDuration)
|
||||
);
|
||||
|
||||
assertEquals(SubscriptionValidator.DURATION_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
|
||||
/**@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when last name contains only whitespace")
|
||||
void testValidateWhitespaceDuration(String whitespace) {
|
||||
SubscriptionInfo subscriptionWithWhitespaceDuration = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), whitespace, "CB");
|
||||
|
||||
NotValidSubscriptionException exception = assertThrows(
|
||||
NotValidSubscriptionException.class,
|
||||
() -> SubscriptionValidator.validate(subscriptionWithWhitespaceDuration)
|
||||
);
|
||||
|
||||
assertEquals(SubscriptionValidator.DURATION_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}**/
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Payment method validation tests")
|
||||
class PaymentMethodValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when payment method is blank")
|
||||
void testValidateBlankPaymentMethod() {
|
||||
SubscriptionInfo subscriptionWithBlankPaymentMethod = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), 12, "");
|
||||
|
||||
NotValidSubscriptionException exception = assertThrows(
|
||||
NotValidSubscriptionException.class,
|
||||
() -> SubscriptionValidator.validate(subscriptionWithBlankPaymentMethod)
|
||||
);
|
||||
|
||||
assertEquals(SubscriptionValidator.PAYMENT_METHOD_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when payment method contains only whitespace")
|
||||
void testValidateWhitespacePhoneNumber(String whitespace) {
|
||||
SubscriptionInfo subscriptionWithWhitespacePaymentMethod = new SubscriptionInfo(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), 12, whitespace);
|
||||
|
||||
NotValidSubscriptionException exception = assertThrows(
|
||||
NotValidSubscriptionException.class,
|
||||
() -> SubscriptionValidator.validate(subscriptionWithWhitespacePaymentMethod)
|
||||
);
|
||||
|
||||
assertEquals(SubscriptionValidator.PAYMENT_METHOD_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
42
src/test/resources/features/livre.feature
Normal file
42
src/test/resources/features/livre.feature
Normal file
@@ -0,0 +1,42 @@
|
||||
# language: en
|
||||
|
||||
Feature: Gerez les livres
|
||||
Background:
|
||||
Given le systeme possedent les livres suivants :
|
||||
| ISBN | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 9781234567890 | Les Mysteres de l'IA | Jean Dupont | TechEditions | 2024-01-15 | 29.99 | 10 | [Technologie, Science] | Un livre fascinant sur l'IA. | Francais |
|
||||
| 9789876543210 | L'Art de la Guerre Moderne | Claire Martin | StrategeBooks | 2023-06-10 | 35.50 | 5 | [Strategie, Histoire] | Analyse des conflits modernes et tactiques. | Francais |
|
||||
| 9781112223334 | Cuisine du Monde | Pierre Lemoine | GourmetEditions | 2022-09-20 | 24.90 | 20 | [Cuisine, Voyage] | Un tour du monde gastronomique en recettes. | Francais |
|
||||
| 9785556667778 | Python pour Debutants | Alice Bernard | CodeMaster | 2021-04-05 | 19.99 | 15 | [Programmation, Informatique] | Apprendre Python pas a pas avec des exercices. | Francais |
|
||||
| 9791032719640 | My Hero Academia |Kohei Horikoshi | Ki-oon | 2025-02-06 | 6.95 | 900 | [Fantastique, Science-fiction, super-heros] | Retrouvez les super-heros du manga phenomene My Hero Academia ! | Francais |
|
||||
|
||||
Scenario: Creer un nouveau livre
|
||||
When Je cree un nouveau livre avec les informations suivantes :
|
||||
| ISBN | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 9789998887776 | L'eveil Spirituel | Olivier Fontaine | ZenBooks | 2020-11-30 | 22.00 | 8 | [Developpement personnel, Spiritualite] | Un guide vers la pleine conscience et la paix interieure. | Francais |
|
||||
Then Un nouveau livre est cree
|
||||
|
||||
Scenario: Modifier les informations d'un livre
|
||||
When Je modifie le livre avec l'ISBN "9791032719640" avec les informations suivantes:
|
||||
| ISBN | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 9791032719640 | My Hero Academia | Kohei Horikoshi | Ki-oon | 2025-02-06 | 6.95 | 999 | [Fantastique, Science-fiction, super-heros] | Retrouvez les super-heros du manga phenomene My Hero Academia ! | Francais |
|
||||
Then Le livre "9791032719640" a les informations suivantes:
|
||||
| ISBN | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 9791032719640 | My Hero Academia | Kohei Horikoshi | Ki-oon | 2025-02-06 | 6.95 | 999 | [Fantastique, Science-fiction, super-heros] | Retrouvez les super-heros du manga phenomene My Hero Academia ! | Francais |
|
||||
|
||||
Scenario: Supprimer un livre
|
||||
When Je supprime le livre avec l'ISBN "9791032719640"
|
||||
Then Le livre "9791032719640" n'existe plus dans le systeme
|
||||
And Le systeme contient 4 livre
|
||||
|
||||
Scenario: Recuperer les informations d'un livre
|
||||
When Je demande les informations du lirve avec l'ISBN "9789876543210"
|
||||
Then Je recupere les informations suivantes:
|
||||
| ISBN | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 9789876543210 | L'Art de la Guerre Moderne | Claire Martin | StrategeBooks | 2023-06-10 | 35.50 | 5 | [Strategie, Histoire] | Analyse des conflits modernes et tactiques. | Francais |
|
||||
|
||||
Scenario: Tentative de creation d'un livre incorrect
|
||||
When J'essaie de creer un nouveau livre avec les informations suivantes :
|
||||
| ISBN | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| abcefg | L'Art de la Guerre Moderne | Claire Martin | StrategeBooks | 2023-06-10 | 35.50 | 5 | [Strategie, Histoire] | Analyse des conflits modernes et tactiques. | Francais |
|
||||
Then La creation echoue
|
153
src/test/resources/features/oder.feature
Normal file
153
src/test/resources/features/oder.feature
Normal file
@@ -0,0 +1,153 @@
|
||||
# language: en
|
||||
|
||||
Feature: Manage customer orders
|
||||
Background:
|
||||
Given the system has the following books in stock:
|
||||
| isbn | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 1234567890123 | The Pragmatic Programmer | Andy Hunt | Addison-Wesley | 2025-06-10 | 39.99 | 10 | FICTION,THRILLER | A practical guide to becoming a better and more efficient software developer. | EN |
|
||||
| 9876543210123 | Clean Code | Robert Martin | Prentice Hall | 2024-01-15 | 49.99 | 5 | FICTION | A handbook of best practices for writing readable, maintainable, and clean code in Java. | EN |
|
||||
And the system has the following customers:
|
||||
| id | firstName | lastName | phoneNumber | loyaltyPoints |
|
||||
| 11111111-1111-1111-1111-111111111111 | Alice | Smith | 0612345678 | 100 |
|
||||
| 22222222-2222-2222-2222-222222222222 | Bob | Martin | 0698765432 | 10 |
|
||||
|
||||
# Create orders
|
||||
|
||||
Scenario: Create an order using credit card
|
||||
When I create a new order with the following information:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | CREDIT_CARD |
|
||||
And the order includes the following books:
|
||||
| bookId | quantity |
|
||||
| 1234567890123 | 2 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 12 Main St. | Paris | 75000 | France |
|
||||
Then a new order is created
|
||||
And the total price is 79.98
|
||||
And customer "11111111-1111-1111-1111-111111111111" now has 100 loyalty points
|
||||
|
||||
Scenario: Create an order using loyalty points
|
||||
When I create a new order with the following information:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | LOYALTY_POINTS |
|
||||
And the order includes the following books:
|
||||
| bookId | quantity |
|
||||
| 9876543210123 | 1 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 42 Book Street | Lyon | 69000 | France |
|
||||
Then a new order is created
|
||||
And the total price is 49.99
|
||||
And 49 loyalty points are deducted
|
||||
And customer "11111111-1111-1111-1111-111111111111" now has 51 loyalty points
|
||||
|
||||
Scenario: Attempt to create an order with invalid address
|
||||
When I create a new order with the following information:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | CREDIT_CARD |
|
||||
And the order includes the following books:
|
||||
| bookId | quantity |
|
||||
| 1234567890123 | 1 |
|
||||
And I try to set the delivery address to:
|
||||
| street | city | postalCode | country |
|
||||
| | | | |
|
||||
Then the creation fails
|
||||
And I receive an error for validation order message containing "Address fields are required"
|
||||
|
||||
Scenario: Attempt to create an order with unknown customer
|
||||
When I create a new order with an unknown customer:
|
||||
| customerId | paymentMethod |
|
||||
| 00000000-0000-0000-0000-000000000000 | CREDIT_CARD |
|
||||
And the order includes the following books:
|
||||
| bookId | quantity |
|
||||
| 1234567890123 | 1 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 12 Main St. | Paris | 75000 | France |
|
||||
Then the creation fails
|
||||
And I receive an error for not found exception message containing "Customer not found"
|
||||
|
||||
Scenario: Attempt to create an order with insufficient loyalty points
|
||||
When I create a new order with insufficient loyalty points:
|
||||
| customerId | paymentMethod |
|
||||
| 22222222-2222-2222-2222-222222222222 | LOYALTY_POINTS |
|
||||
And the order includes the following books:
|
||||
| bookId | quantity |
|
||||
| 9876543210123 | 1 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 42 Book Street | Lyon | 69000 | France |
|
||||
Then the creation fails
|
||||
And I receive an error for illegal order exception message containing "Not enough loyalty points"
|
||||
|
||||
Scenario: Attempt to order more books than available stock
|
||||
When I create a new order with the following information:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | CREDIT_CARD |
|
||||
And I try to order more books than available stock:
|
||||
| bookId | quantity |
|
||||
| 1234567890123 | 50 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 12 Main St. | Paris | 75000 | France |
|
||||
Then the creation fails
|
||||
And I receive an error for illegal order exception message containing "Insufficient book stock"
|
||||
|
||||
Scenario: Attempt to create an order with invalid payment method
|
||||
When I create a new order with an invalid payment method:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | UNKNOWN |
|
||||
And the order includes the following books:
|
||||
| bookId | quantity |
|
||||
| 1234567890123 | 1 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 12 Main St. | Paris | 75000 | France |
|
||||
Then the creation fails
|
||||
And I receive an error for validation order message containing "Payment method is not valid"
|
||||
|
||||
Scenario: Attempt to create an order with unknown book
|
||||
When I create a new order with the following information:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | CREDIT_CARD |
|
||||
And I try to order a book that does not exist:
|
||||
| bookId | quantity |
|
||||
| unknownBookId | 1 |
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 12 Main St. | Paris | 75000 | France |
|
||||
Then the creation fails
|
||||
And I receive an error for not found exception message containing "Book not found"
|
||||
|
||||
Scenario: Attempt to create an order with empty book list
|
||||
When I create a new order with the following information:
|
||||
| customerId | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | CREDIT_CARD |
|
||||
And the order includes no books
|
||||
And the delivery address is:
|
||||
| street | city | postalCode | country |
|
||||
| 12 Main St. | Paris | 75000 | France |
|
||||
Then the creation fails
|
||||
And I receive an error for validation order message containing "Book list cannot be empty"
|
||||
|
||||
#Get orders
|
||||
|
||||
Scenario: Retrieve an order by ID
|
||||
Given an order with ID "abcd1234-5678-90ef-1234-567890abcdef" exists for customer "11111111-1111-1111-1111-111111111111"
|
||||
When I retrieve the order by ID "abcd1234-5678-90ef-1234-567890abcdef"
|
||||
Then I receive the order details
|
||||
|
||||
Scenario: Retrieve all orders for a customer
|
||||
When I request all orders for customer "11111111-1111-1111-1111-111111111111"
|
||||
Then I receive a list of orders
|
||||
|
||||
Scenario: Attempt to retrieve an unknown order
|
||||
When I retrieve the order by ID "unknown-order-id"
|
||||
Then the retrieval fails
|
||||
And I receive an error for not found exception message containing "Order not found"
|
||||
|
||||
Scenario: Attempt to retrieve orders for an unknown customer
|
||||
When I request all orders for customer "00000000-0000-0000-0000-000000000000"
|
||||
Then the retrieval fails
|
||||
And I receive an error for not found exception message containing "Customer not found"
|
28
src/test/resources/features/subscription.feature
Normal file
28
src/test/resources/features/subscription.feature
Normal file
@@ -0,0 +1,28 @@
|
||||
# language: en
|
||||
|
||||
Feature: Manage customer subscription
|
||||
Background:
|
||||
Given the system has the following customers:
|
||||
| customerId | firstName | lastName | phoneNumer | pointsFidelite |
|
||||
| 11111111-1111-1111-1111-111111111111 | John | Doe | 0612345678 | 100 |
|
||||
| 22222222-2222-2222-2222-222222222222 | Bob | Dupond | 0687654321 | 50 |
|
||||
| 33333333-3333-3333-3333-333333333333 | Alice | Untel | 0698765432 | 0 |
|
||||
|
||||
Scenario: Create a new subscription
|
||||
When I create a new subscription with CB:
|
||||
| customerId | duration | paymentMethod |
|
||||
| 11111111-1111-1111-1111-111111111111 | 12 | CB |
|
||||
Then a new subscription is created
|
||||
|
||||
Scenario: Create a new subscription
|
||||
When I create a new subscription with Paypal:
|
||||
| customerId | duration | paymentMethod |
|
||||
| 22222222-2222-2222-2222-222222222222 | 24 | Paypal |
|
||||
Then a new subscription is created
|
||||
|
||||
Scenario: Attempt to create a subscription with invalid duration:
|
||||
When I try to create a new subscription with the following information:
|
||||
| customerId | duration | paymentMethod |
|
||||
| 33333333-3333-3333-3333-333333333333 | 0 | CB |
|
||||
Then the subsription duration creation fails
|
||||
And I receive an error for validation subscription message containing "Duration must be positive"
|
Reference in New Issue
Block a user