From 9aa759c940f93ad412003be557518d89bb111670 Mon Sep 17 00:00:00 2001 From: Kang Min Date: Mon, 5 Feb 2024 22:59:30 +0900 Subject: [PATCH] =?UTF-8?q?feature:=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC?= =?UTF-8?q?=20API=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CategoryController.java | 12 ++--- .../ootdzip/category/data/CategoryRes.java | 47 +++++++++++++++--- .../ootdzip/category/data/CategorySearch.java | 13 ----- .../ootdzip/category/domain/Category.java | 23 +++++++++ .../category/service/CategoryService.java | 36 +++++--------- .../category/service/CategoryServiceTest.java | 48 +++++++++++++++++++ 6 files changed, 128 insertions(+), 51 deletions(-) delete mode 100644 src/main/java/zip/ootd/ootdzip/category/data/CategorySearch.java create mode 100644 src/test/java/zip/ootd/ootdzip/category/service/CategoryServiceTest.java diff --git a/src/main/java/zip/ootd/ootdzip/category/controller/CategoryController.java b/src/main/java/zip/ootd/ootdzip/category/controller/CategoryController.java index a08c680a..16cc27d2 100644 --- a/src/main/java/zip/ootd/ootdzip/category/controller/CategoryController.java +++ b/src/main/java/zip/ootd/ootdzip/category/controller/CategoryController.java @@ -4,14 +4,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import zip.ootd.ootdzip.category.data.CategoryRes; -import zip.ootd.ootdzip.category.data.CategorySearch; -import zip.ootd.ootdzip.category.data.CategoryType; import zip.ootd.ootdzip.category.service.CategoryService; import zip.ootd.ootdzip.common.response.ApiResponse; @@ -23,9 +21,9 @@ public class CategoryController { private final CategoryService categoryService; - @GetMapping("/") - public ApiResponse> getCategories(@RequestParam CategoryType categoryType, - @RequestParam Long parentCategoryId) { - return new ApiResponse<>(categoryService.getCategories(new CategorySearch(categoryType, parentCategoryId))); + @GetMapping("") + @Operation(summary = "카테고리 조회 API", description = "모든 카테고리 조회하는 API") + public ApiResponse> getCategories() { + return new ApiResponse<>(categoryService.getCategories()); } } diff --git a/src/main/java/zip/ootd/ootdzip/category/data/CategoryRes.java b/src/main/java/zip/ootd/ootdzip/category/data/CategoryRes.java index 3c6ae72d..1a963c0e 100644 --- a/src/main/java/zip/ootd/ootdzip/category/data/CategoryRes.java +++ b/src/main/java/zip/ootd/ootdzip/category/data/CategoryRes.java @@ -1,21 +1,54 @@ package zip.ootd.ootdzip.category.data; -import lombok.Data; +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; import zip.ootd.ootdzip.category.domain.Category; -@Data +@Getter +@NoArgsConstructor public class CategoryRes { private Long id; private String name; - private CategoryType type; + private List detailCategories; + + @Builder + private CategoryRes(Long id, String name, List detailCategories) { + this.id = id; + this.name = name; + this.detailCategories = detailCategories; + } + + public static CategoryRes of(Category largeCategory, List detailCategories) { + return CategoryRes.builder() + .id(largeCategory.getId()) + .name(largeCategory.getName()) + .detailCategories(detailCategories.stream().map(DetailCategory::of).toList()) + .build(); + } + + static class DetailCategory { + + private final Long id; + + private final String name; - public CategoryRes(Category category) { + @Builder + private DetailCategory(Long id, String name) { + this.id = id; + this.name = name; + } - this.id = category.getId(); - this.name = category.getName(); - this.type = category.getType(); + public static DetailCategory of(Category category) { + return DetailCategory.builder() + .id(category.getId()) + .name(category.getName()) + .build(); + } } } diff --git a/src/main/java/zip/ootd/ootdzip/category/data/CategorySearch.java b/src/main/java/zip/ootd/ootdzip/category/data/CategorySearch.java deleted file mode 100644 index 1f928201..00000000 --- a/src/main/java/zip/ootd/ootdzip/category/data/CategorySearch.java +++ /dev/null @@ -1,13 +0,0 @@ -package zip.ootd.ootdzip.category.data; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class CategorySearch { - - private CategoryType categoryType; - - private Long parentCategoryId; -} diff --git a/src/main/java/zip/ootd/ootdzip/category/domain/Category.java b/src/main/java/zip/ootd/ootdzip/category/domain/Category.java index 1a46884b..8eaf66f6 100644 --- a/src/main/java/zip/ootd/ootdzip/category/domain/Category.java +++ b/src/main/java/zip/ootd/ootdzip/category/domain/Category.java @@ -39,4 +39,27 @@ public class Category { @JoinColumn(name = "parent_id", nullable = true) private Category parentCategory; + @Builder + private Category(String name, CategoryType type, Category parentCategory) { + this.name = name; + this.type = type; + this.parentCategory = parentCategory; + } + + public static Category createLargeCategoryBy(String name) { + return Category.builder() + .name(name) + .type(CategoryType.LargeCategory) + .parentCategory(null) + .build(); + } + + public static Category createDetailCategoryBy(String name, Category parentCategory) { + return Category.builder() + .name(name) + .type(CategoryType.DetailCategory) + .parentCategory(parentCategory) + .build(); + } + } diff --git a/src/main/java/zip/ootd/ootdzip/category/service/CategoryService.java b/src/main/java/zip/ootd/ootdzip/category/service/CategoryService.java index 20310032..000b4fc5 100644 --- a/src/main/java/zip/ootd/ootdzip/category/service/CategoryService.java +++ b/src/main/java/zip/ootd/ootdzip/category/service/CategoryService.java @@ -1,17 +1,15 @@ package zip.ootd.ootdzip.category.service; +import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import zip.ootd.ootdzip.category.data.CategoryRes; -import zip.ootd.ootdzip.category.data.CategorySearch; import zip.ootd.ootdzip.category.data.CategoryType; import zip.ootd.ootdzip.category.domain.Category; import zip.ootd.ootdzip.category.repository.CategoryRepository; -import zip.ootd.ootdzip.common.exception.CustomException; -import zip.ootd.ootdzip.common.exception.code.ErrorCode; @Service @RequiredArgsConstructor @@ -19,32 +17,22 @@ public class CategoryService { private final CategoryRepository categoryRepository; - public List getCategories(CategorySearch request) { - //TODO : 페이징 넣을 지 확인 필요 - List findCategories; + public List getCategories() { + List findCategories = categoryRepository.findAll(); + List result = new ArrayList<>(); - // 대분류 카테고리 조회 시 모든 대분류 카테고리 조회 - if (request.getCategoryType().equals(CategoryType.LargeCategory)) { - findCategories = categoryRepository.findCategoriesByType(request.getCategoryType()); - return findCategories.stream() - .map(CategoryRes::new) + for (Category parentCategory : findCategories.stream() + .filter(x -> x.getType().equals(CategoryType.LargeCategory)) + .toList()) { + List detailCategories = findCategories.stream() + .filter(x -> x.getParentCategory() != null + && x.getParentCategory().getId().equals(parentCategory.getId())) .toList(); - } - - // 소분류 카테고리 조회 시 전달받은 부모 카테고리의 하위 카테고리 조회 - Category parentCategory = categoryRepository.findById(request.getParentCategoryId()) - .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_ERROR)); - - findCategories = categoryRepository.findCategoriesByParentCategoryAndType(parentCategory, - request.getCategoryType()); - if (findCategories == null || findCategories.isEmpty()) { - throw new CustomException(ErrorCode.NOT_FOUND_ERROR); + result.add(CategoryRes.of(parentCategory, detailCategories)); } - return findCategories.stream() - .map(CategoryRes::new) - .toList(); + return result; } } diff --git a/src/test/java/zip/ootd/ootdzip/category/service/CategoryServiceTest.java b/src/test/java/zip/ootd/ootdzip/category/service/CategoryServiceTest.java new file mode 100644 index 00000000..318325d2 --- /dev/null +++ b/src/test/java/zip/ootd/ootdzip/category/service/CategoryServiceTest.java @@ -0,0 +1,48 @@ +package zip.ootd.ootdzip.category.service; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import zip.ootd.ootdzip.IntegrationTestSupport; +import zip.ootd.ootdzip.category.data.CategoryRes; +import zip.ootd.ootdzip.category.domain.Category; +import zip.ootd.ootdzip.category.repository.CategoryRepository; + +class CategoryServiceTest extends IntegrationTestSupport { + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private CategoryService categoryService; + + @DisplayName("상위 카테고리 ID로 카테고리를 조회한다.") + @Test + void getCategories() { + // given + Category parentCategory = Category.createLargeCategoryBy("부모카테고리1"); + Category savedParentCategory = categoryRepository.save(parentCategory); + + Category detailCategory = Category.createDetailCategoryBy("하위카테고리1", savedParentCategory); + Category savedDetailCategory = categoryRepository.save(detailCategory); + + // when + List result = categoryService.getCategories(); + + //then + assertThat(result).hasSize(1) + .extracting("id", "name") + .contains(tuple(savedParentCategory.getId(), savedParentCategory.getName())); + + assertThat(result.get(0).getDetailCategories()).hasSize(1) + .extracting("id", "name") + .contains(tuple(savedDetailCategory.getId(), savedDetailCategory.getName())); + + } + +}