Début de la feature avec des tests de base sur les variables #3
@@ -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";
|
||||||
|
|||||||
+1
-1
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user