ajout du validator pour les livres + tests
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
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 {
|
||||
|
||||
public static final int TITLE_MAX_LENGTH = 255;
|
||||
|
||||
public static final String ISBN_MUST_BE_POSITIVE = "Isbn must be a positive number";
|
||||
public static final String TITLE_CANNOT_BE_BLANK = "Title cannot be blank";
|
||||
public static final String TITLE_TOO_LONG = "Title cannot exceed " + TITLE_MAX_LENGTH + " characters";
|
||||
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 PUBLICATION_DATE_REQUIRED = "Publication date is required";
|
||||
public static final String PRICE_MUST_BE_POSITIVE = "Price must be strictly positive";
|
||||
public static final String QUANTITY_MUST_BE_POSITIVE_OR_ZERO = "Quantity must be >= 0";
|
||||
public static final String CATEGORIES_REQUIRED = "At least one category is required";
|
||||
public static final String LANGUAGE_CANNOT_BE_BLANK = "Language cannot be blank";
|
||||
|
||||
private BookValidator() {
|
||||
|
||||
}
|
||||
|
||||
public static void validate(BookInfo book) throws NotValidBookException {
|
||||
validateIsbn(book);
|
||||
validateTitle(book);
|
||||
validateAuthor(book);
|
||||
validatePublisher(book);
|
||||
validatePublicationDate(book);
|
||||
validatePrice(book);
|
||||
validateQuantity(book);
|
||||
validateCategories(book);
|
||||
validateLanguage(book);
|
||||
}
|
||||
|
||||
private static void validateIsbn(BookInfo book) throws NotValidBookException {
|
||||
if (book.isbn() <= 0) {
|
||||
throw new NotValidBookException(ISBN_MUST_BE_POSITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateTitle(BookInfo book) throws NotValidBookException {
|
||||
if (book.title() == null || book.title().isBlank()) {
|
||||
throw new NotValidBookException(TITLE_CANNOT_BE_BLANK);
|
||||
}
|
||||
if (book.title().length() > TITLE_MAX_LENGTH) {
|
||||
throw new NotValidBookException(TITLE_TOO_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateAuthor(BookInfo book) throws NotValidBookException {
|
||||
if (book.author() == null || book.author().isBlank()) {
|
||||
throw new NotValidBookException(AUTHOR_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePublisher(BookInfo book) throws NotValidBookException {
|
||||
if (book.publisher() == null || book.publisher().isBlank()) {
|
||||
throw new NotValidBookException(PUBLISHER_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePublicationDate(BookInfo book) throws NotValidBookException {
|
||||
if (book.publicationDate() == null) {
|
||||
throw new NotValidBookException(PUBLICATION_DATE_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePrice(BookInfo book) throws NotValidBookException {
|
||||
if (book.price() <= 0) {
|
||||
throw new NotValidBookException(PRICE_MUST_BE_POSITIVE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateQuantity(BookInfo book) throws NotValidBookException {
|
||||
if (book.quantity() < 0) {
|
||||
throw new NotValidBookException(QUANTITY_MUST_BE_POSITIVE_OR_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateCategories(BookInfo book) throws NotValidBookException {
|
||||
if (book.categories() == null || book.categories().isEmpty()) {
|
||||
throw new NotValidBookException(CATEGORIES_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateLanguage(BookInfo book) throws NotValidBookException {
|
||||
if (book.language() == null || book.language().isBlank()) {
|
||||
throw new NotValidBookException(LANGUAGE_CANNOT_BE_BLANK);
|
||||
}
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
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.entity.Category;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
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 static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BookValidatorTest {
|
||||
|
||||
private BookInfo valid() {
|
||||
return new BookInfo(
|
||||
9780321125217L,
|
||||
"Domain-Driven Design",
|
||||
"Eric Evans",
|
||||
"Addison-Wesley",
|
||||
LocalDate.of(2003, 8, 22),
|
||||
54.99,
|
||||
10,
|
||||
List.of(Category.SCIENCE),
|
||||
"Tackling complexity in the heart of software",
|
||||
"EN"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should accept a valid BookInfo")
|
||||
void testValidBook() {
|
||||
assertDoesNotThrow(() -> BookValidator.validate(valid()));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("ISBN validation")
|
||||
class IsbnTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(longs = {0L, -1L, -9999L})
|
||||
@DisplayName("Should reject ISBN that is not strictly positive")
|
||||
void testInvalidIsbn(long isbn) {
|
||||
BookInfo info = new BookInfo(isbn, "T", "A", "P", LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.ISBN_MUST_BE_POSITIVE, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Title validation")
|
||||
class TitleTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"", " ", "\t", "\n"})
|
||||
@DisplayName("Should reject blank title")
|
||||
void testBlankTitle(String title) {
|
||||
BookInfo info = new BookInfo(1L, title, "A", "P", LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.TITLE_CANNOT_BE_BLANK, ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject null title")
|
||||
void testNullTitle() {
|
||||
BookInfo info = new BookInfo(1L, null, "A", "P", LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.TITLE_CANNOT_BE_BLANK, ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject title longer than 255 characters")
|
||||
void testTitleTooLong() {
|
||||
String longTitle = "a".repeat(256);
|
||||
BookInfo info = new BookInfo(1L, longTitle, "A", "P", LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.TITLE_TOO_LONG, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Author / Publisher validation")
|
||||
class AuthorPublisherTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"", " ", "\t"})
|
||||
@DisplayName("Should reject blank author")
|
||||
void testBlankAuthor(String author) {
|
||||
BookInfo info = new BookInfo(1L, "T", author, "P", LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.AUTHOR_CANNOT_BE_BLANK, ex.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"", " ", "\t"})
|
||||
@DisplayName("Should reject blank publisher")
|
||||
void testBlankPublisher(String publisher) {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", publisher, LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.PUBLISHER_CANNOT_BE_BLANK, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Date / Price / Quantity validation")
|
||||
class NumericTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject null publication date")
|
||||
void testNullDate() {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", "P", null, 1.0, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.PUBLICATION_DATE_REQUIRED, ex.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(doubles = {0.0, -0.01, -10.0})
|
||||
@DisplayName("Should reject non-positive price")
|
||||
void testNonPositivePrice(double price) {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", "P", LocalDate.now(), price, 0, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.PRICE_MUST_BE_POSITIVE, ex.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {-1, -100})
|
||||
@DisplayName("Should reject negative quantity")
|
||||
void testNegativeQuantity(int quantity) {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", "P", LocalDate.now(), 1.0, quantity, List.of(Category.SCIENCE), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.QUANTITY_MUST_BE_POSITIVE_OR_ZERO, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Categories / Language validation")
|
||||
class MetadataTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject empty categories")
|
||||
void testEmptyCategories() {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", "P", LocalDate.now(), 1.0, 0, List.of(), "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.CATEGORIES_REQUIRED, ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should reject null categories")
|
||||
void testNullCategories() {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", "P", LocalDate.now(), 1.0, 0, null, "", "EN");
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.CATEGORIES_REQUIRED, ex.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"", " ", "\t"})
|
||||
@DisplayName("Should reject blank language")
|
||||
void testBlankLanguage(String language) {
|
||||
BookInfo info = new BookInfo(1L, "T", "A", "P", LocalDate.now(), 1.0, 0, List.of(Category.SCIENCE), "", language);
|
||||
NotValidBookException ex = assertThrows(NotValidBookException.class, () -> BookValidator.validate(info));
|
||||
assertEquals(BookValidator.LANGUAGE_CANNOT_BE_BLANK, ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user