维护入口
This commit is contained in:
@@ -12,7 +12,6 @@ import com.mzh.library.exception.DaoException;
|
||||
import com.mzh.library.service.impl.BookServiceImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -48,6 +47,12 @@ public final class BookServiceCheck {
|
||||
require("You do not have permission to manage books.".equals(denied.getMessage()),
|
||||
"reader write should return permission message");
|
||||
|
||||
ServiceResult<Long> deniedCategory = service.createCategory(reader,
|
||||
category(0L, "Reader Category", "Denied category"));
|
||||
require(!deniedCategory.isSuccessful(), "reader category create should fail");
|
||||
require("You do not have permission to manage books.".equals(deniedCategory.getMessage()),
|
||||
"reader category write should return permission message");
|
||||
|
||||
ServiceResult<Long> created = service.createBook(librarian,
|
||||
book(0L, "BK-1002", "Service Test", "Test Author", 1L, 2, 1, BookStatus.AVAILABLE));
|
||||
require(created.isSuccessful(), "librarian should create a valid book");
|
||||
@@ -63,6 +68,13 @@ public final class BookServiceCheck {
|
||||
require(updated.isSuccessful(), "librarian should update a valid book");
|
||||
require(dao.findById(createdId).get().getAvailableCopies() == 3, "update should persist available copies");
|
||||
|
||||
ServiceResult<Void> deleteUsedCategory = service.deleteCategory(librarian, 1L);
|
||||
require(!deleteUsedCategory.isSuccessful(), "used category delete should fail");
|
||||
require("Category is used by existing books and cannot be deleted.".equals(deleteUsedCategory.getMessage()),
|
||||
"used category delete should return a safe specific message");
|
||||
require(deleteUsedCategory.getErrors().containsKey("category"),
|
||||
"used category delete should return a category-level field error");
|
||||
|
||||
ServiceResult<List<Book>> search = service.searchBooks(new BookSearchCriteria("BK-1003", "", "", null));
|
||||
require(search.isSuccessful(), "search should succeed");
|
||||
require(search.getData().size() == 1, "search should find updated identifier");
|
||||
@@ -71,6 +83,26 @@ public final class BookServiceCheck {
|
||||
require(deleted.isSuccessful(), "librarian should delete a book");
|
||||
require(!dao.findById(createdId).isPresent(), "delete should remove the record");
|
||||
|
||||
ServiceResult<Long> createdCategory = service.createCategory(librarian,
|
||||
category(0L, "Architecture", "Design and systems"));
|
||||
require(createdCategory.isSuccessful(), "librarian should create a category");
|
||||
long categoryId = createdCategory.getData();
|
||||
|
||||
ServiceResult<Long> duplicateCategory = service.createCategory(librarian,
|
||||
category(0L, "Architecture", "Duplicate category"));
|
||||
require(!duplicateCategory.isSuccessful(), "duplicate category should fail");
|
||||
require(duplicateCategory.getErrors().containsKey("name"), "duplicate category should target name field");
|
||||
|
||||
ServiceResult<Void> updatedCategory = service.updateCategory(librarian,
|
||||
category(categoryId, "Software Architecture", "Updated category"));
|
||||
require(updatedCategory.isSuccessful(), "librarian should update a category");
|
||||
require("Software Architecture".equals(dao.findCategoryById(categoryId).get().getName()),
|
||||
"category update should persist the new name");
|
||||
|
||||
ServiceResult<Void> deletedCategory = service.deleteCategory(librarian, categoryId);
|
||||
require(deletedCategory.isSuccessful(), "unused category should be deleted");
|
||||
require(!dao.findCategoryById(categoryId).isPresent(), "category delete should remove unused category");
|
||||
|
||||
BookService failingService = new BookServiceImpl(new FailingBookDao());
|
||||
ServiceResult<List<Book>> unavailable = failingService.searchBooks(new BookSearchCriteria());
|
||||
require(!unavailable.isSuccessful(), "DAO failure should not escape service");
|
||||
@@ -98,6 +130,14 @@ public final class BookServiceCheck {
|
||||
return book;
|
||||
}
|
||||
|
||||
private static BookCategory category(long id, String name, String description) {
|
||||
BookCategory category = new BookCategory();
|
||||
category.setId(id);
|
||||
category.setName(name);
|
||||
category.setDescription(description);
|
||||
return category;
|
||||
}
|
||||
|
||||
private static void require(boolean condition, String message) {
|
||||
if (!condition) {
|
||||
throw new AssertionError(message);
|
||||
@@ -106,14 +146,70 @@ public final class BookServiceCheck {
|
||||
|
||||
private static final class InMemoryBookDao implements BookDao {
|
||||
private final Map<Long, Book> books = new LinkedHashMap<>();
|
||||
private final Map<Long, BookCategory> categories = new LinkedHashMap<>();
|
||||
private long nextId = 1L;
|
||||
private long nextCategoryId = 2L;
|
||||
|
||||
private InMemoryBookDao() {
|
||||
categories.put(1L, category(1L, "Computer Science", "Programming books"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookCategory> findAllCategories() {
|
||||
BookCategory category = new BookCategory();
|
||||
category.setId(1L);
|
||||
category.setName("Computer Science");
|
||||
return Collections.singletonList(category);
|
||||
List<BookCategory> results = new ArrayList<>();
|
||||
for (BookCategory category : categories.values()) {
|
||||
results.add(copy(category));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BookCategory> findCategoryById(long id) {
|
||||
return Optional.ofNullable(categories.get(id)).map(this::copy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BookCategory> findCategoryByName(String name) {
|
||||
for (BookCategory category : categories.values()) {
|
||||
if (category.getName().equals(name)) {
|
||||
return Optional.of(copy(category));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long createCategory(BookCategory category) {
|
||||
long id = nextCategoryId++;
|
||||
BookCategory stored = copy(category);
|
||||
stored.setId(id);
|
||||
categories.put(id, stored);
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateCategory(BookCategory category) {
|
||||
if (!categories.containsKey(category.getId())) {
|
||||
return false;
|
||||
}
|
||||
categories.put(category.getId(), copy(category));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteCategory(long id) {
|
||||
return categories.remove(id) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBooksByCategoryId(long categoryId) {
|
||||
int count = 0;
|
||||
for (Book book : books.values()) {
|
||||
if (book.getCategoryId() == categoryId) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,6 +274,10 @@ public final class BookServiceCheck {
|
||||
copy.setCategoryName(source.getCategoryName());
|
||||
return copy;
|
||||
}
|
||||
|
||||
private BookCategory copy(BookCategory source) {
|
||||
return category(source.getId(), source.getName(), source.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class FailingBookDao implements BookDao {
|
||||
@@ -186,6 +286,36 @@ public final class BookServiceCheck {
|
||||
throw new DaoException("Simulated category failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BookCategory> findCategoryById(long id) {
|
||||
throw new DaoException("Simulated category find failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BookCategory> findCategoryByName(String name) {
|
||||
throw new DaoException("Simulated category find failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long createCategory(BookCategory category) {
|
||||
throw new DaoException("Simulated category create failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateCategory(BookCategory category) {
|
||||
throw new DaoException("Simulated category update failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteCategory(long id) {
|
||||
throw new DaoException("Simulated category delete failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBooksByCategoryId(long categoryId) {
|
||||
throw new DaoException("Simulated category count failure", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> search(BookSearchCriteria criteria) {
|
||||
throw new DaoException("Simulated search failure", null);
|
||||
|
||||
Reference in New Issue
Block a user