This commit is contained in:
aissi
2026-03-24 17:26:18 +01:00
parent dab8a636d0
commit 5e1031bd71
9 changed files with 254 additions and 0 deletions
@@ -0,0 +1,14 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book;
import java.time.LocalDate;
public record BookInfo(
String isbn,
String title,
String author,
String publisher,
LocalDate publicationDate,
double price,
int stockInitial
) {
}
@@ -0,0 +1,29 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.entity;
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.IllegalCustomerPointException;
import java.rmi.server.UID;
import java.time.LocalDate;
import java.util.UUID;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class Book {
//private UUID id;
private String isbn;
private String title;
private String author;
private String publisher;
private LocalDate publicationDate;
private double price;
private int stock;
}
/*
public void setRandomUUID() {
this.id = UUID.randomUUID();
}
*/
@@ -0,0 +1,14 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
import java.text.MessageFormat;
import java.util.UUID;
public class BookNotFoundException {
public static final String THE_BOOK_WITH_ID_DOES_NOT_EXISTS = "The book with id {0} does not exist";
public BookNotFoundException(UUID uuid) {
super(); //super(MessageFormat.format(THE_BOOK_WITH_ID_DOES_NOT_EXISTS, uuid)); à corriger
}
}
@@ -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,32 @@
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 lombok.NoArgsConstructor;
@NoArgsConstructor
public final class BookRepository {
private final List<Book> books = new ArrayList<>();
public Book save(Book newBook) {
this.findByIsbn(newBook.getIsbn()).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 List<Book> findAll() {
return books;
}
public void deleteAll() {
books.clear();
}
}
@@ -0,0 +1,31 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.usecase;
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.NotValidBookException;
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
import fr.iut_fbleau.but3.dev62.mylibrary.book.validator.BookValidator;
public final class BookUseCase {
private final BookRepository bookRepository;
public BookUseCase(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public String registerNewBook(BookInfo newBook) throws NotValidBookException {
BookValidator.validate(newBook);
Book bookToSave = Book.builder()
.isbn(newBook.isbn())
.title(newBook.title())
.author(newBook.author())
.publisher(newBook.publisher())
.publicationDate(newBook.publicationDate())
.price(newBook.price())
.stock(newBook.stockInitial())
.build();
Book savedBook = bookRepository.save(bookToSave);
return savedBook.getIsbn();
}
}
@@ -0,0 +1,38 @@
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;
public final class BookValidator {
private BookValidator() {
}
public static void validate(BookInfo bookInfo) throws NotValidBookException {
if (bookInfo == null) {
throw new NotValidBookException("Book cannot be null");
}
if (isBlank(bookInfo.isbn())) {
throw new NotValidBookException("ISBN is required");
}
if (isBlank(bookInfo.title())) {
throw new NotValidBookException("Title is required");
}
if (isBlank(bookInfo.author())) {
throw new NotValidBookException("Author is required");
}
if (isBlank(bookInfo.publisher())) {
throw new NotValidBookException("Publisher is required");
}
if (bookInfo.price() <= 0) {
throw new NotValidBookException("Price must be positive");
}
if (bookInfo.stockInitial() < 0) {
throw new NotValidBookException("Stock must be greater or equal to 0");
}
}
private static boolean isBlank(String value) {
return value == null || value.isBlank();
}
}
@@ -0,0 +1,87 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.usecase;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
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.NotValidBookException;
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
import java.time.LocalDate;
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;
@ExtendWith(MockitoExtension.class)
class BookUseCaseTest {
@Mock
private BookRepository bookRepository;
@InjectMocks
private BookUseCase bookUseCase;
@Nested
@DisplayName("Register new book tests")
class RegisterNewBookTests {
@Test
@DisplayName("Should register a new book and return ISBN")
void shouldRegisterBookAndReturnIsbn() throws NotValidBookException {
BookInfo validBookInfo = new BookInfo(
"9783161484100",
"Clean Code",
"Robert C. Martin",
"Prentice Hall",
LocalDate.of(2008, 8, 1),
42.50,
10
);
Book savedBook = Book.builder()
.isbn("9783161484100")
.title("Clean Code")
.author("Robert C. Martin")
.publisher("Prentice Hall")
.publicationDate(LocalDate.of(2008, 8, 1))
.price(42.50)
.stock(10)
.build();
when(bookRepository.save(any(Book.class))).thenReturn(savedBook);
String isbn = bookUseCase.registerNewBook(validBookInfo);
assertNotNull(isbn);
assertEquals("9783161484100", isbn);
verify(bookRepository, times(1)).save(any(Book.class));
}
@Test
@DisplayName("Should throw when required field is empty")
void shouldThrowWhenRequiredFieldIsEmpty() {
BookInfo invalidBookInfo = new BookInfo(
"9783161484100",
"",
"Robert C. Martin",
"Prentice Hall",
LocalDate.of(2008, 8, 1),
42.50,
10
);
assertThrows(NotValidBookException.class, () -> bookUseCase.registerNewBook(invalidBookInfo));
verify(bookRepository, never()).save(any(Book.class));
}
}
}
@@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.*;
import java.util.UUID;
class CustomerTest {
@Test