test des usecase créer

This commit is contained in:
2026-04-28 18:18:23 +02:00
parent 099cb403ca
commit 4d47cdd9a0
4 changed files with 351 additions and 7 deletions
@@ -4,7 +4,6 @@ import fr.iut_fbleau.but3.dev62.mylibrary.book.BookDetails;
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.BookSalesInfo; import fr.iut_fbleau.but3.dev62.mylibrary.book.BookSalesInfo;
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException; import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.NotValidCustomerException;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
@@ -24,7 +23,7 @@ public class BookValidator {
private BookValidator() { private BookValidator() {
} }
public static void validate(BookInfo newBook) throws NotValidCustomerException { public static void validate(BookInfo newBook) throws NotValidBookException {
validateISBN(newBook); validateISBN(newBook);
validateTitle(newBook); validateTitle(newBook);
validateAuthor(newBook); validateAuthor(newBook);
@@ -32,12 +31,12 @@ public class BookValidator {
validateDate(newBook); validateDate(newBook);
} }
public static void validate(BookSalesInfo newBook) throws NotValidCustomerException { public static void validate(BookSalesInfo newBook) throws NotValidBookException {
validatePrice(newBook); validatePrice(newBook);
validateStock(newBook); validateStock(newBook);
} }
public static void validate(BookDetails newBook) throws NotValidCustomerException { public static void validate(BookDetails newBook) throws NotValidBookException {
validateCategories(newBook); validateCategories(newBook);
validateLanguage(newBook); validateLanguage(newBook);
} }
@@ -15,8 +15,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class BookTest { public class BookTest {
@Test @Test
@DisplayName("Builder should create a valid Customer instance") @DisplayName("Builder should create a valid Book instance")
void testCustomerBuilder() { void testBookBuilder() {
String isbn = "1234567891012"; String isbn = "1234567891012";
String title = "La vie de Maxime"; String title = "La vie de Maxime";
String author = "Marvin Aubert"; String author = "Marvin Aubert";
@@ -199,7 +199,7 @@ public class BookRepositoryTest {
class DeleteOperations { class DeleteOperations {
@BeforeEach @BeforeEach
void setUpCustomers() { void setUpBooks() {
repository.save(book1); repository.save(book1);
repository.save(book2); repository.save(book2);
} }
@@ -0,0 +1,345 @@
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.BookDetails;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookSalesInfo;
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 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.LocalDate;
import java.util.ArrayList;
import java.util.Optional;
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.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.never;
@ExtendWith(MockitoExtension.class)
public class BookUseCaseTest {
@Mock
private BookRepository bookRepository;
@InjectMocks
private BookUseCase bookUseCase;
private String bookIsbn;
private ArrayList<String> categories;
private LocalDate date;
private Book testBook;
private BookInfo validBookInfo;
private BookDetails validBookDetails;
private BookSalesInfo validBookSalesInfo;
@BeforeEach
void setUp() {
bookIsbn = "1234567891012";
date = LocalDate.of(2026, 3, 24);
categories = new ArrayList<>();
categories.add("Thriller");
categories.add("Biographie");
testBook = Book.builder()
.isbn(bookIsbn)
.title("La vie de Maxime")
.author("Marvin AUbert")
.editor("Kioon")
.date(date)
.price(12.99)
.stock(50)
.categories(categories)
.description("C'était un brave partit trop tôt")
.language("Français")
.build();
validBookInfo = new BookInfo(bookIsbn,"La vie de Maxime", "Marvin AUbert", "Kioon", date);
validBookSalesInfo = BookSalesInfo.builder()
.price(12.99)
.stock(50)
.build();
validBookDetails = BookDetails.builder()
.categories(categories)
.description("C'était un brave partit trop tôt")
.language("Français")
.build();
}
@Nested
@DisplayName("Register Book tests")
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(bookIsbn,"", "", "", date);
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("1234567891012")).thenReturn(Optional.of(testBook));
Optional<BookDTO> foundBook = bookUseCase.findBookByIsbn("1234567891012");
assertTrue(foundBook.isPresent());
assertEquals(testBook.getIsbn(), foundBook.get().getIsbn());
assertEquals(testBook.getTitle(), foundBook.get().getTitle());
verify(bookRepository, times(1)).findByIsbn("1234567891012");
}
@Test
@DisplayName("Should return empty Optional when isbn doesn't exist")
void testFindBookByIsbn() {
when(bookRepository.findByIsbn("1656546262516")).thenReturn(Optional.empty());
Optional<BookDTO> foundBook = bookUseCase.findBookByIsbn("1656546262516");
assertTrue(foundBook.isEmpty());
verify(bookRepository, times(1)).findByIsbn("1656546262516");
}
}
@Nested
@DisplayName("Update book tests")
class UpdateBookTests {
@Test
@DisplayName("Should update book when valid data is provided")
void testUpdateBookWithValidData() throws BookNotFoundException, NotValidBookException {
when(bookRepository.findByIsbn(bookIsbn)).thenReturn(Optional.of(testBook));
Book updatedBook = Book.builder()
.isbn(bookIsbn)
.title("La vie de Maxime")
.author("Updated")
.editor("Kioon")
.date(date)
.price(12.99)
.stock(50)
.categories(categories)
.description("C'était un brave partit trop tôt")
.language("Français")
.build();
when(bookRepository.save(any(Book.class))).thenReturn(updatedBook);
BookInfo updateInfo = new BookInfo(bookIsbn, "La vie de Maxime", "Updated", "Kioon", date);
BookSalesInfo updateSalesInfo = BookSalesInfo.builder()
.price(12.99)
.stock(50)
.build();
BookDetails updateDetails = BookDetails.builder()
.categories(categories)
.description("C'était un brave partit trop tôt")
.language("Français")
.build();
BookDTO result = BookUseCase.updateBook(updateInfo, updateSalesInfo, updateDetails);
assertNotNull(result);
assertEquals(bookIsbn, result.getIsbn());
assertEquals("La vie de Maxime", result.getTitle());
assertEquals("Updated", result.getAuthor());
assertEquals("Kioon", result.getEditor());
assertEquals(date, result.getDate());
assertEquals(12.99, result.getPrice());
assertEquals(50, result.getStock());
assertEquals(categories, result.getCategories());
assertEquals("C'était un brave partit trop tôt", result.getDescription());
assertEquals("Français", result.getLanguage());
verify(bookRepository, times(1)).findByIsbn(bookIsbn);
verify(bookRepository, times(1)).save(any(Book.class));
}
@Test
@DisplayName("Should throw exception when book isbn doesn't exist")
void testUpdateBookNotFound() {
String nonExistentIsbn = "1656546262516";
when(bookRepository.findByIsbn(nonExistentIsbn)).thenReturn(Optional.empty());
BookInfo updateInfo = new BookInfo(nonExistentIsbn, "La vie de Maxime", "Updated", "Kioon", date);
BookSalesInfo updateSalesInfo = BookSalesInfo.builder()
.price(12.99)
.stock(50)
.build();
BookDetails updateDetails = BookDetails.builder()
.categories(categories)
.description("C'était un brave partit trop tôt")
.language("Français")
.build();
assertThrows(BookNotFoundException.class,
() -> bookUseCase.updateBook(updateInfo, updateSalesInfo, updateDetails));
verify(bookRepository, times(1)).findByIsbn(nonExistentIsbn);
verify(bookRepository, never()).save(any(Book.class));
}
@Test
@DisplayName("Should throw exception when update data is not valid")
void testUpdateBookWithInvalidData() {
BookInfo invalidUpdateInfo = new BookInfo(bookIsbn,"", "", "", date);
BookSalesInfo invalidUpdateSalesInfo = BookSalesInfo.builder()
.price(0)
.stock(-3)
.build();
BookDetails invalidUpdateDetails = BookDetails.builder()
.categories(categories)
.description("")
.language("")
.build();
assertThrows(NotValidBookException.class,
() -> bookUseCase.updateBook(invalidUpdateInfo, invalidUpdateSalesInfo, invalidUpdateDetails));
verify(bookRepository, never()).findByIsbn(any(String.class));
verify(bookRepository, never()).save(any(Book.class));
}
}
@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 = "1656546262516";
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));
}
}
@Nested
@DisplayName("Stock copies tests")
class StockCopiesTests {
@Test
@DisplayName("Should add stock copies to book")
void testAddStockCopies() throws BookNotFoundException {
when(bookRepository.findByIsbn(bookIsbn)).thenReturn(Optional.of(testBook));
when(bookRepository.save(testBook)).thenReturn(testBook);
int initialCopies = testBook.getStock();
int copiesToAdd = 50;
int expectedCopies = initialCopies + copiesToAdd;
int newCopies = bookUseCase.addStockCopies(bookIsbn, copiesToAdd);
assertEquals(expectedCopies, newCopies);
assertEquals(expectedCopies, testBook.getStock());
verify(bookRepository, times(1)).findByIsbn(bookIsbn);
verify(bookRepository, times(1)).save(testBook);
}
@Test
@DisplayName("Should throw exception when adding copies to non-existent book")
void testAddStockCopiesToNonExistentBook() {
String nonExistentIsbn = "1656546262516";
when(bookRepository.findByIsbn(nonExistentIsbn)).thenReturn(Optional.empty());
assertThrows(BookNotFoundException.class,
() -> bookUseCase.addStockCopies(nonExistentIsbn, 50));
verify(bookRepository, times(1)).findByIsbn(nonExistentIsbn);
verify(bookRepository, never()).save(any(Book.class));
}
@Test
@DisplayName("Should subtract stock copies from book")
void testSubtractStockCopies() throws BookNotFoundException, IllegalBookCpoiesException {
when(bookRepository.findByIsbn(bookIsbn)).thenReturn(Optional.of(testBook));
when(bookRepository.save(testBook)).thenReturn(testBook);
int initialCopies = testBook.getStock();
int copiesToRemove = 30;
int expectedCopies = initialCopies - copiesToRemove;
int newCopies = bookUseCase.subtractStockCopies(bookIsbn, copiesToRemove);
assertEquals(expectedCopies, newCopies);
assertEquals(expectedCopies, testBook.getStock());
verify(bookRepository, times(1)).findByIsbn(bookIsbn);
verify(bookRepository, times(1)).save(testBook);
}
@Test
@DisplayName("Should throw exception when trying to remove more copies than available")
void testSubtractTooManyStockCopies() {
when(bookRepository.findByIsbn(bookIsbn)).thenReturn(Optional.of(testBook));
int copiesToRemove = 200;
assertThrows(IllegalBookCpoiesException.class,
() -> bookUseCase.subtractStockCopies(bookIsbn, copiesToRemove));
verify(bookRepository, times(1)).findByIsbn(bookIsbn);
verify(bookRepository, never()).save(any(Book.class));
}
@Test
@DisplayName("Should throw exception when subtracting copies from non-existent book")
void testSubtractStockCopiesFromNonExistentBook() {
String nonExistentIsbn = "1656546262516";
when(bookRepository.findByIsbn(nonExistentIsbn)).thenReturn(Optional.empty());
assertThrows(BookNotFoundException.class,
() -> bookUseCase.subtractStockCopies(nonExistentIsbn, 50));
verify(bookRepository, times(1)).findByIsbn(nonExistentIsbn);
verify(bookRepository, never()).save(any(Book.class));
}
}
}