From 0f2eac76d36bab5a6007098dd7bfbf5b5149a10e Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Tue, 16 Jul 2024 15:09:59 +0900 Subject: [PATCH 1/8] =?UTF-8?q?docs:=204=EC=A3=BC=EC=B0=A8=201=EB=8B=A8?= =?UTF-8?q?=EA=B3=84=20=EA=B5=AC=ED=98=84=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 75f82d8fa..409cc5148 100644 --- a/README.md +++ b/README.md @@ -1 +1,41 @@ -# spring-gift-enhancement \ No newline at end of file +# spring-gift-enhancement + +## 구현할 기능 목록 + +### 1단계 + +### 상품 카테고리 + +TO DO +- [ ] 카테코리 엔티티 클래스 정의 +- [ ] 상품 정보에 카테고리 추가 + +고려해야할 사항 +- 상품에는 항상 하나의 카테고리가 있어야 한다. + - 상품 카테고리는 수정할 수 있다. + - 관리자 화면에서 상품을 추가할 때 카테고리를 지정할 수 있다. +- 카테고리는 1차 카테고리만 있으며 2차 카테고리는 고려하지 않는다. +- 카테고리의 예시는 아래와 같다. + - 교환권, 상품권, 뷰티, 패션, 식품, 리빙/도서, 레저/스포츠, 아티스트/캐릭터, 유아동/반려, 디지털/가전, 카카오프렌즈, 트렌드 선물, 백화점, ... + +**Request** +```http request +GET /api/categories HTTP/1.1 +``` + +**Response** +```http request +HTTP/1.1 200 +Content-Type: application/json + +[ + { + "id": 91, + "name": "교환권", + "color": "#6c95d1", + "imageUrl": "https://gift-s.kakaocdn.net/dn/gift/images/m640/dimm_theme.png", + "description": "" + } +] + +``` From 9367d81b0006fa865a2fbfacee3371c5b32889dc Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Wed, 17 Jul 2024 12:47:29 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EA=B8=B0=EB=B3=B8=20CRUD=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 카테고리 추가 - 카테고리 전체 조회 - 카테고리 정보 수정 - 카테고리 삭제 - 카테고리 단일 조회 - 카테고리 속 상품 조회 --- .../gift/category/CategoryController.java | 54 +++++++++ .../gift/category/CategoryRepository.java | 12 ++ .../gift/category/CategoryRequestDto.java | 5 + .../gift/category/CategoryResponseDto.java | 5 + .../java/gift/category/CategoryService.java | 103 ++++++++++++++++++ src/main/java/gift/category/Cateogory.java | 75 +++++++++++++ .../gift/exception/AlreadyExistCategory.java | 8 ++ .../java/gift/exception/InvalidCategory.java | 8 ++ .../java/gift/product/ProductRepository.java | 2 + 9 files changed, 272 insertions(+) create mode 100644 src/main/java/gift/category/CategoryController.java create mode 100644 src/main/java/gift/category/CategoryRepository.java create mode 100644 src/main/java/gift/category/CategoryRequestDto.java create mode 100644 src/main/java/gift/category/CategoryResponseDto.java create mode 100644 src/main/java/gift/category/CategoryService.java create mode 100644 src/main/java/gift/category/Cateogory.java create mode 100644 src/main/java/gift/exception/AlreadyExistCategory.java create mode 100644 src/main/java/gift/exception/InvalidCategory.java diff --git a/src/main/java/gift/category/CategoryController.java b/src/main/java/gift/category/CategoryController.java new file mode 100644 index 000000000..a0fd4644f --- /dev/null +++ b/src/main/java/gift/category/CategoryController.java @@ -0,0 +1,54 @@ +package gift.category; + +import java.util.List; +import org.springframework.http.HttpEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/categories") +public class CategoryController { + + private final CategoryService categoryService; + + public CategoryController(CategoryService categoryService) { + this.categoryService = categoryService; + } + + @GetMapping + public List getAllCategory() { + return categoryService.getAllCategory(); + } + + @PostMapping + public CategoryResponseDto addCateogory(@RequestBody CategoryRequestDto categoryRequestDto) { + return categoryService.postCategory(categoryRequestDto); + } + + @PutMapping("/{id}") + public CategoryResponseDto updateCategory(@PathVariable Long id, @RequestBody CategoryRequestDto categoryRequestDto) { + return categoryService.putCategory(id, categoryRequestDto); + } + + @DeleteMapping("/{id}") + public HttpEntity deleteCategory(@PathVariable Long id) { + return categoryService.deleteCategoryById(id); + } + + @GetMapping("/{id}") + public CategoryResponseDto getCategoryById(@PathVariable Long id) { + return categoryService.getCategoryById(id); + } + + @GetMapping("/products/{id}") + public List getProducts(@PathVariable Long id) { + return categoryService.getProductsInCategory(id); + } + +} diff --git a/src/main/java/gift/category/CategoryRepository.java b/src/main/java/gift/category/CategoryRepository.java new file mode 100644 index 000000000..83ec04aff --- /dev/null +++ b/src/main/java/gift/category/CategoryRepository.java @@ -0,0 +1,12 @@ +package gift.category; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CategoryRepository extends JpaRepository { + + Optional findByName(String name); + +} diff --git a/src/main/java/gift/category/CategoryRequestDto.java b/src/main/java/gift/category/CategoryRequestDto.java new file mode 100644 index 000000000..cf88b04b9 --- /dev/null +++ b/src/main/java/gift/category/CategoryRequestDto.java @@ -0,0 +1,5 @@ +package gift.category; + +public record CategoryRequestDto(String name, String color, String imageUrl, String description) { + +} diff --git a/src/main/java/gift/category/CategoryResponseDto.java b/src/main/java/gift/category/CategoryResponseDto.java new file mode 100644 index 000000000..648726d80 --- /dev/null +++ b/src/main/java/gift/category/CategoryResponseDto.java @@ -0,0 +1,5 @@ +package gift.category; + +public record CategoryResponseDto(Long id, String name, String color, String imageUrl, String description) { + +} diff --git a/src/main/java/gift/category/CategoryService.java b/src/main/java/gift/category/CategoryService.java new file mode 100644 index 000000000..2e63315f8 --- /dev/null +++ b/src/main/java/gift/category/CategoryService.java @@ -0,0 +1,103 @@ +package gift.category; + +import gift.exception.AlreadyExistCategory; +import gift.exception.InvalidCategory; +import gift.product.Product; +import gift.product.ProductRepository; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +@Service +public class CategoryService { + + private final CategoryRepository categoryRepository; + private final ProductRepository productRepository; + + public CategoryService(CategoryRepository categoryRepository, ProductRepository productRepository) { + this.categoryRepository = categoryRepository; + this.productRepository = productRepository; + } + + public List getAllCategory() { + return categoryRepository.findAll().stream() + .map(category -> new CategoryResponseDto( + category.getId(), + category.getName(), + category.getColor(), + category.getImageUrl(), + category.getDescription())) + .collect(Collectors.toList()); + } + + public CategoryResponseDto postCategory(CategoryRequestDto categoryRequestDto) { + Cateogory cateogory = new Cateogory( + categoryRequestDto.name(), + categoryRequestDto.color(), + categoryRequestDto.imageUrl(), + categoryRequestDto.description() + ); + if (categoryRepository.findByName(cateogory.getName()).isPresent()) { + throw new AlreadyExistCategory("동일한 카테고리가 이미 존재합니다."); + } + + categoryRepository.saveAndFlush(cateogory); + + return new CategoryResponseDto( + cateogory.getId(), + cateogory.getName(), + cateogory.getColor(), + cateogory.getImageUrl(), + cateogory.getDescription() + ); + } + + public CategoryResponseDto putCategory(Long id, CategoryRequestDto categoryRequestDto) { + Cateogory cateogory = categoryRepository.findById(id) + .orElseThrow(() -> new InvalidCategory("유효하지 않은 카테고리입니다.")); + + cateogory.update(categoryRequestDto.name(), categoryRequestDto.color(), categoryRequestDto.imageUrl(), categoryRequestDto.description()); + categoryRepository.saveAndFlush(cateogory); + + return new CategoryResponseDto( + cateogory.getId(), + cateogory.getName(), + cateogory.getColor(), + cateogory.getImageUrl(), + cateogory.getDescription() + ); + } + + public HttpEntity deleteCategoryById(Long id) { + Cateogory cateogory = categoryRepository.findById(id) + .orElseThrow(() -> new InvalidCategory("유효하지 않은 카테고리입니다.")); + + categoryRepository.delete(cateogory); + + return ResponseEntity.ok("성공적으로 삭제되었습니다"); + } + + public CategoryResponseDto getCategoryById(Long id) { + Cateogory cateogory = categoryRepository.findById(id) + .orElseThrow(() -> new InvalidCategory("유효하지 않은 카테고리입니다.")); + + return new CategoryResponseDto( + cateogory.getId(), + cateogory.getName(), + cateogory.getColor(), + cateogory.getImageUrl(), + cateogory.getDescription() + ); + } + + public List getProductsInCategory(Long id) { + List products = productRepository.findAllByCateogory_Id(id); + + return products.stream() + .map(Product::getId) + .collect(Collectors.toList()); + } + +} diff --git a/src/main/java/gift/category/Cateogory.java b/src/main/java/gift/category/Cateogory.java new file mode 100644 index 000000000..a6503a6bc --- /dev/null +++ b/src/main/java/gift/category/Cateogory.java @@ -0,0 +1,75 @@ +package gift.category; + +import gift.product.Product; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "category") +public class Cateogory { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false, unique = true) + private String name; + + @Column(name = "color", nullable = false) + private String color; + + @Column(name = "image_url", nullable = false) + private String imageUrl; + + @Column(name = "description", nullable = false) + private String description; + + @OneToMany + @JoinColumn + private List products = new ArrayList<>(); + + protected Cateogory() { + } + + public Cateogory(String name, String color, String imageUrl, String description) { + this.name = name; + this.color = color; + this.imageUrl = imageUrl; + this.description = description; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getColor() { + return color; + } + + public String getImageUrl() { + return imageUrl; + } + + public String getDescription() { + return description; + } + + public void update(String name, String color, String imageUrl, String description) { + this.name = name; + this.color = color; + this.imageUrl = imageUrl; + this.description = description; + } +} diff --git a/src/main/java/gift/exception/AlreadyExistCategory.java b/src/main/java/gift/exception/AlreadyExistCategory.java new file mode 100644 index 000000000..c4ff04c33 --- /dev/null +++ b/src/main/java/gift/exception/AlreadyExistCategory.java @@ -0,0 +1,8 @@ +package gift.exception; + +public class AlreadyExistCategory extends RuntimeException{ + + public AlreadyExistCategory(String message) { + super(message); + } +} diff --git a/src/main/java/gift/exception/InvalidCategory.java b/src/main/java/gift/exception/InvalidCategory.java new file mode 100644 index 000000000..6ca79f518 --- /dev/null +++ b/src/main/java/gift/exception/InvalidCategory.java @@ -0,0 +1,8 @@ +package gift.exception; + +import java.util.NoSuchElementException; + +public class InvalidCategory extends NoSuchElementException { + + public InvalidCategory(String message) {super(message);} +} diff --git a/src/main/java/gift/product/ProductRepository.java b/src/main/java/gift/product/ProductRepository.java index 928f1aead..777be96de 100644 --- a/src/main/java/gift/product/ProductRepository.java +++ b/src/main/java/gift/product/ProductRepository.java @@ -13,4 +13,6 @@ public interface ProductRepository extends JpaRepository, Page findAll(Pageable pageable); + List findAllByCateogory_Id(Long id); + } From 9f9cccef27018330fd224288255bcd6ec12986de Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Wed, 17 Jul 2024 12:48:11 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EC=9D=98=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/product/Product.java | 18 ++++++- .../java/gift/product/ProductController.java | 6 +++ .../java/gift/product/ProductRequestDto.java | 3 +- .../java/gift/product/ProductResponseDto.java | 2 +- .../java/gift/product/ProductService.java | 50 ++++++++++++++----- 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/main/java/gift/product/Product.java b/src/main/java/gift/product/Product.java index 9f1fb93f5..b8971770b 100644 --- a/src/main/java/gift/product/Product.java +++ b/src/main/java/gift/product/Product.java @@ -1,10 +1,13 @@ package gift.product; +import gift.category.Cateogory; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; @Entity @@ -24,13 +27,18 @@ public class Product { @Column(name = "image_url", nullable = false) private String imageUrl; + @ManyToOne + @JoinColumn(name = "category_id") + private Cateogory cateogory; + protected Product() { } - public Product(String name, int price, String imageUrl) { + public Product(String name, int price, String imageUrl, Cateogory cateogory) { this.name = name; this.price = price; this.imageUrl = imageUrl; + this.cateogory = cateogory; } public void update(String name, int price, String imageUrl) { @@ -39,6 +47,10 @@ public void update(String name, int price, String imageUrl) { this.imageUrl = imageUrl; } + public void changeCategory(Cateogory cateogory) { + this.cateogory = cateogory; + } + public Long getId() { return id; } @@ -54,5 +66,9 @@ public int getPrice() { public String getImageUrl() { return imageUrl; } + + public Cateogory getCateogory() { + return cateogory; + } } diff --git a/src/main/java/gift/product/ProductController.java b/src/main/java/gift/product/ProductController.java index 56fc506d8..c3b599139 100644 --- a/src/main/java/gift/product/ProductController.java +++ b/src/main/java/gift/product/ProductController.java @@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -54,4 +55,9 @@ public ProductResponseDto updateProduct(@PathVariable Long id, @RequestBody @Val public HttpEntity deleteProduct(@PathVariable Long id) { return productService.deleteProductById(id); } + + @PutMapping("/category/{id}") + public ProductResponseDto changeCategory(@PathVariable(name="id") Long productID, @RequestParam Long categoryId) { + return productService.putCategory(productID, categoryId); + } } diff --git a/src/main/java/gift/product/ProductRequestDto.java b/src/main/java/gift/product/ProductRequestDto.java index 90c009c41..1ae901f97 100644 --- a/src/main/java/gift/product/ProductRequestDto.java +++ b/src/main/java/gift/product/ProductRequestDto.java @@ -14,5 +14,6 @@ public record ProductRequestDto( @Min(value = 1,message = "상품 가격을 입력해주세요") int price, @NotBlank(message = "상품 url을 등록해주세요") - String url) { } + String url, + Long categoryId) { } diff --git a/src/main/java/gift/product/ProductResponseDto.java b/src/main/java/gift/product/ProductResponseDto.java index 245190e78..63d27d350 100644 --- a/src/main/java/gift/product/ProductResponseDto.java +++ b/src/main/java/gift/product/ProductResponseDto.java @@ -1,6 +1,6 @@ package gift.product; -public record ProductResponseDto(Long id, String name, int price, String url) { +public record ProductResponseDto(Long id, String name, int price, String url, Long categoryId) { } diff --git a/src/main/java/gift/product/ProductService.java b/src/main/java/gift/product/ProductService.java index 27d8e77cd..2fe5305dc 100644 --- a/src/main/java/gift/product/ProductService.java +++ b/src/main/java/gift/product/ProductService.java @@ -1,5 +1,7 @@ package gift.product; +import gift.category.CategoryRepository; +import gift.exception.InvalidCategory; import gift.exception.InvalidProduct; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -15,9 +17,11 @@ public class ProductService { private final ProductRepository productRepository; + private final CategoryRepository categoryRepository; - public ProductService(ProductRepository productRepository) { + public ProductService(ProductRepository productRepository, CategoryRepository categoryRepository) { this.productRepository = productRepository; + this.categoryRepository = categoryRepository; } public Page getAllProducts(Pageable pageable) { @@ -27,7 +31,8 @@ public Page getAllProducts(Pageable pageable) { product.getId(), product.getName(), product.getPrice(), - product.getImageUrl())); + product.getImageUrl(), + product.getCateogory().getId())); } public Optional getProductById(Long id) { @@ -36,20 +41,23 @@ public Optional getProductById(Long id) { product.getId(), product.getName(), product.getPrice(), - product.getImageUrl())); + product.getImageUrl(), + product.getCateogory().getId())); } public ProductResponseDto postProduct(ProductRequestDto productRequestDto) { Product product = productRepository.saveAndFlush(new Product( productRequestDto.name(), productRequestDto.price(), - productRequestDto.url() + productRequestDto.url(), + categoryRepository.findById(productRequestDto.categoryId()).orElseThrow() )); return new ProductResponseDto( product.getId(), product.getName(), product.getPrice(), - product.getImageUrl() + product.getImageUrl(), + product.getCateogory().getId() ); } @@ -64,17 +72,35 @@ public ProductResponseDto putProduct(Long id, ProductRequestDto productRequestDt product.getId(), product.getName(), product.getPrice(), - product.getImageUrl() + product.getImageUrl(), + product.getCateogory().getId() + ); + } + + public ProductResponseDto putCategory(Long productId, Long categoryId) { + Product product = productRepository.findById(productId) + .orElseThrow(() -> new InvalidProduct("유효하지 않은 상품입니다")); + + product.changeCategory(categoryRepository.findById(categoryId) + .orElseThrow(() -> new InvalidCategory("유효하지 않은 카테고리입니다"))); + + productRepository.saveAndFlush(product); + + return new ProductResponseDto( + product.getId(), + product.getName(), + product.getPrice(), + product.getImageUrl(), + product.getCateogory().getId() ); } public HttpEntity deleteProductById(Long id) { - Optional product = productRepository.findById(id); - if (product.isEmpty()) { - throw new InvalidProduct("유효하지 않은 상품입니다"); - } else { - productRepository.deleteById(id); - } + Product product = productRepository.findById(id) + .orElseThrow(() -> new InvalidProduct("유효하지 않은 상품입니다")); + + productRepository.deleteById(id); + return ResponseEntity.ok("성공적으로 삭제되었습니다"); } From c3d21c9015d0132de5c2ef934b214139705c2297 Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Wed, 17 Jul 2024 12:48:23 +0900 Subject: [PATCH 4/8] =?UTF-8?q?docs:=20=EB=A6=AC=EB=93=9C=EB=AF=B8=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 409cc5148..5b89c76fb 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ TO DO - [ ] 카테코리 엔티티 클래스 정의 - [ ] 상품 정보에 카테고리 추가 + +- [ ] 카테고리 기본 CRUD +- [ ] 카테고리에 속한 상품 조회 - 테스트 코드 +- [ ] 상품을 등록할 떼 카테고리 설정 +- [ ] 상품의 카테고리 수정 ex) A 상품의 카테고리를 '교환권' 카테고리에서 '과제면회권' 카테고리로 변경한다 + 고려해야할 사항 - 상품에는 항상 하나의 카테고리가 있어야 한다. - 상품 카테고리는 수정할 수 있다. From f4338e7d29b697d45551ee499409a2c4e818dca0 Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Wed, 17 Jul 2024 14:22:15 +0900 Subject: [PATCH 5/8] test: CategoryRepositoryTest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 카테고리 저장 테스트 - 단일 카테고리 조회 테스트 - 모든 카테고리 조회 테스트 - 카테고리 수정 테스트 - 카테고리 삭제 테스트 - 카테고리 속 상품 조회 테스트 (@DataJpaTest 사용) --- .../gift/category/CategoryRepositoryTest.java | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/test/java/gift/category/CategoryRepositoryTest.java diff --git a/src/test/java/gift/category/CategoryRepositoryTest.java b/src/test/java/gift/category/CategoryRepositoryTest.java new file mode 100644 index 000000000..aec450323 --- /dev/null +++ b/src/test/java/gift/category/CategoryRepositoryTest.java @@ -0,0 +1,130 @@ +package gift.category; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.InstanceOfAssertFactories.LIST; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.util.List; +import gift.product.Product; +import gift.product.ProductRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +class CategoryRepositoryTest { + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private ProductRepository productRepository; + +// @BeforeEach +// void setCategoryRepository() { +// categoryRepository.save(new Cateogory("교환권","쌈@뽕한 블루","www","여름")); +// categoryRepository.save(new Cateogory("과제면제권","방학","www.com","학교")); +// categoryRepository.save(new Cateogory("라우브","스틸더","www.show","키야")); +// } + +// @BeforeEach +// void setProductRepository() { +// productRepository.save(new Product("사과", 2000, "www",)); +// productRepository.save(new Product("참외",4000,"달다!",1)); +// productRepository.save(new Product("바나나", 3000,"맛있다!",2)); +// } + + @Test + @DisplayName("카테고리 저장 테스트") + void save() { + Cateogory expected = new Cateogory("교환권","쌈@뽕한 블루","www","여름"); + Cateogory actual = categoryRepository.save(expected); + + assertAll( + () -> assertThat(actual).isEqualTo(expected) + ); + } + + @Test + @DisplayName("단일 카테고리 조회 테스트") + void findById() { + Cateogory expected = new Cateogory("교환권","쌈@뽕한 블루","www","여름"); + categoryRepository.save(expected); + Cateogory actual = categoryRepository.findById(expected.getId()).get(); + + assertAll( + () -> assertThat(actual.getId()).isNotNull(), + () -> assertThat(actual.getId()).isEqualTo(expected.getId()), + () -> assertThat(actual.getName()).isEqualTo("교환권"), + () -> assertThat(actual.getColor()).isEqualTo("쌈@뽕한 블루"), + () -> assertThat(actual.getImageUrl()).isEqualTo("www"), + () -> assertThat(actual.getDescription()).isEqualTo("여름") + ); + } + + @Test + @DisplayName("모든 카테고리 조회 테스트") + void findAll() { + Cateogory cateogory1 = new Cateogory("교환권","쌈@뽕한 블루","www","여름"); + Cateogory cateogory2 = new Cateogory("과제면제권","방학","www.com","학교"); + Cateogory cateogory3 = new Cateogory("라우브","스틸더","www.show","키야"); + categoryRepository.save(cateogory1); + categoryRepository.save(cateogory2); + categoryRepository.save(cateogory3); + + List categoryList = categoryRepository.findAll(); + + assertAll( + ()-> assertThat(categoryList.size()).isEqualTo(3) + ); + } + + @Test + @DisplayName("카테고리 수정 테스트") + void update() { + Cateogory category = new Cateogory("교환권","쌈@뽕한 블루","www","여름"); + + category.update("과제면제권","방학","www.com","학교"); + + assertAll( + () -> assertThat(category.getName()).isEqualTo("과제면제권"), + () -> assertThat(category.getColor()).isEqualTo("방학"), + () -> assertThat(category.getImageUrl()).isEqualTo("www.com"), + () -> assertThat(category.getDescription()).isEqualTo("학교") + ); + } + + @Test + @DisplayName("카테고리 삭제 테스트") + void delete() { + Cateogory category = new Cateogory("교환권","쌈@뽕한 블루","www","여름"); + categoryRepository.save(category); + categoryRepository.deleteById(category.getId()); + + List isCategory = categoryRepository.findById(category.getId()).stream().toList(); + + assertAll( + () -> assertThat(isCategory.size()).isEqualTo(0) + ); + } + + @Test + @DisplayName("카테고리 속 상품 조회 테스트") + void findProductInCategory() { + Cateogory cateogory = new Cateogory("교환권","쌈@뽕한 블루","www","여름"); + categoryRepository.save(cateogory); + productRepository.save(new Product("사과", 2000, "www", cateogory)); + productRepository.save(new Product("참외",4000,"달다!", cateogory)); + + List productList = productRepository.findAllByCateogory_Id(cateogory.getId()); + + assertAll( + () -> assertThat(productList.size()).isEqualTo(2) + ); + } + +} From 9189a3d00f06c2a8dfccb8a67ee7244279dad0d0 Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Wed, 17 Jul 2024 15:50:13 +0900 Subject: [PATCH 6/8] =?UTF-8?q?chore:=20mockito=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 905b5b5fb..225233b58 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,7 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' implementation 'org.projectlombok:lombok' implementation("org.springframework.boot:spring-boot-starter-data-jpa") + testImplementation 'org.mockito:mockito-junit-jupiter:5.2.0' } tasks.named('test') { From 43c6b69bd29fef8732205a859786e687c3b6b74c Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Thu, 18 Jul 2024 19:25:35 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=EA=B0=80=20=EC=B6=94=EA=B0=80=EB=90=9C=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=97=94=ED=8B=B0=ED=8B=B0=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=ED=95=98=EC=97=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/wishlist/Wishlist.java | 4 +++ .../gift/category/CategoryRepositoryTest.java | 12 +++---- .../gift/product/ProductControllerTest.java | 6 ++-- .../gift/product/ProductRepositoryTest.java | 34 ++++++++++++++----- .../gift/wishlist/WishlistRepositoryTest.java | 18 ++++++++-- 5 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/main/java/gift/wishlist/Wishlist.java b/src/main/java/gift/wishlist/Wishlist.java index db65c6042..04c948942 100644 --- a/src/main/java/gift/wishlist/Wishlist.java +++ b/src/main/java/gift/wishlist/Wishlist.java @@ -35,6 +35,10 @@ public Wishlist(Member member, Product product) { this.product = product; } + public Long getId() { + return id; + } + public Member getMember() { return member; } diff --git a/src/test/java/gift/category/CategoryRepositoryTest.java b/src/test/java/gift/category/CategoryRepositoryTest.java index aec450323..cc5d4640d 100644 --- a/src/test/java/gift/category/CategoryRepositoryTest.java +++ b/src/test/java/gift/category/CategoryRepositoryTest.java @@ -24,12 +24,12 @@ class CategoryRepositoryTest { @Autowired private ProductRepository productRepository; -// @BeforeEach -// void setCategoryRepository() { -// categoryRepository.save(new Cateogory("교환권","쌈@뽕한 블루","www","여름")); -// categoryRepository.save(new Cateogory("과제면제권","방학","www.com","학교")); -// categoryRepository.save(new Cateogory("라우브","스틸더","www.show","키야")); -// } + @BeforeEach + void setCategoryRepository() { + categoryRepository.save(new Cateogory("교환권","쌈@뽕한 블루","www","여름")); + categoryRepository.save(new Cateogory("과제면제권","방학","www.com","학교")); + categoryRepository.save(new Cateogory("라우브","스틸더","www.show","키야")); + } // @BeforeEach // void setProductRepository() { diff --git a/src/test/java/gift/product/ProductControllerTest.java b/src/test/java/gift/product/ProductControllerTest.java index ee2f0ffe3..e7593947c 100644 --- a/src/test/java/gift/product/ProductControllerTest.java +++ b/src/test/java/gift/product/ProductControllerTest.java @@ -33,7 +33,7 @@ void port() { @Test void create() { var url = "http://localhost:" + port + "/api/products"; - var request = new ProductRequestDto("사과",2000,"www"); + var request = new ProductRequestDto("사과",2000,"www", 1L); var requestEntity = new RequestEntity<>(request, POST, URI.create(url)); var actual = restTemplate.exchange(requestEntity, String.class); assertThat(actual.getStatusCode()).isEqualTo(OK); @@ -54,7 +54,7 @@ void setUp() { baseUrl = "http://localhost:" + port + "/api/products"; // 각 테스트 전에 제품 생성 - var request = new ProductRequestDto("사과", 2000, "www"); + var request = new ProductRequestDto("사과", 2000, "www", 1L); var requestEntity = new RequestEntity<>(request, POST, URI.create(baseUrl)); var createResponse = restTemplate.exchange(requestEntity, String.class); assertThat(createResponse.getStatusCode()).isEqualTo(OK); @@ -95,7 +95,7 @@ void update() { Long productId = 1L; var updateUrl = "http://localhost:" + port + "/api/products/" + productId; - var update = new ProductRequestDto("파김치", 10000, "www.com"); + var update = new ProductRequestDto("파김치", 10000, "www.com", 1L); var requestUpdate = new RequestEntity<>(update, PUT, URI.create(updateUrl)); var updateResponse = restTemplate.exchange(requestUpdate, String.class); assertThat(updateResponse.getStatusCode()).isEqualTo(OK); diff --git a/src/test/java/gift/product/ProductRepositoryTest.java b/src/test/java/gift/product/ProductRepositoryTest.java index d612219b5..dc08e3a3b 100644 --- a/src/test/java/gift/product/ProductRepositoryTest.java +++ b/src/test/java/gift/product/ProductRepositoryTest.java @@ -3,7 +3,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import gift.category.CategoryRepository; +import gift.category.Cateogory; import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -17,10 +20,20 @@ class ProductRepositoryTest { @Autowired private ProductRepository productRepository; + @Autowired + private CategoryRepository categoryRepository; + + @BeforeEach + void setCategoryRepository() { + categoryRepository.save(new Cateogory("교환권","쌈@뽕한 블루","www","여름")); + categoryRepository.save(new Cateogory("과제면제권","방학","www.com","학교")); + categoryRepository.save(new Cateogory("라우브","스틸더","www.show","키야")); + } + @Test @DisplayName("상품 저장 테스트") void save() { - Product expected = new Product("사과",2000,"www"); + Product expected = new Product("사과",2000,"www",categoryRepository.findById(1L).get()); Product actual = productRepository.save(expected); assertThat(actual).isEqualTo(expected); } @@ -31,7 +44,8 @@ void findById() { String expectedName = "사과"; int expectedPrice = 2000; String expectedImageUrl = "www"; - Product expected = new Product(expectedName, expectedPrice, expectedImageUrl); + Cateogory cateogory = categoryRepository.findById(1L).get(); + Product expected = new Product(expectedName, expectedPrice, expectedImageUrl, cateogory); productRepository.save(expected); Product actual = productRepository.findById(expected.getId()).get(); assertThat(actual).isEqualTo(expected); @@ -41,16 +55,17 @@ void findById() { () -> assertThat(actual.getId()).isEqualTo(expected.getId()), () -> assertThat(actual.getName()).isEqualTo(expectedName), () -> assertThat(actual.getPrice()).isEqualTo(expectedPrice), - () -> assertThat(actual.getImageUrl()).isEqualTo(expectedImageUrl) + () -> assertThat(actual.getImageUrl()).isEqualTo(expectedImageUrl), + () -> assertThat(actual.getCateogory()).isEqualTo(cateogory) ); } @Test @DisplayName("모든 상품 조회 테스트") void findAll() { - Product product1 = new Product("사과", 2000, "www"); - Product product2 = new Product("앵우", 100000, "www.com"); - Product product3 = new Product("econo", 30000, "error"); + Product product1 = new Product("사과", 2000, "www", categoryRepository.findById(1L).get()); + Product product2 = new Product("앵우", 100000, "www.com", categoryRepository.findById(2L).get()); + Product product3 = new Product("econo", 30000, "error", categoryRepository.findById(3L).get()); productRepository.save(product1); productRepository.save(product2); productRepository.save(product3); @@ -65,21 +80,22 @@ void findAll() { @Test @DisplayName("상품 수정 테스트") void update() { - Product product = new Product("사과", 2000, "www"); + Product product = new Product("사과", 2000, "www",categoryRepository.findById(1L).get()); product.update("바나나", 3000, "www.com"); assertAll( () -> assertThat(product.getName()).isEqualTo("바나나"), () -> assertThat(product.getPrice()).isEqualTo(3000), - () -> assertThat(product.getImageUrl()).isEqualTo("www.com") + () -> assertThat(product.getImageUrl()).isEqualTo("www.com"), + () -> assertThat(product.getCateogory()).isEqualTo(categoryRepository.findById(1L).get()) ); } @Test @DisplayName("상품 삭제 테스트") void delete() { - Product product = new Product("사과", 2000, "www"); + Product product = new Product("사과", 2000, "www", categoryRepository.findById(1L).get()); productRepository.save(product); productRepository.deleteById(product.getId()); diff --git a/src/test/java/gift/wishlist/WishlistRepositoryTest.java b/src/test/java/gift/wishlist/WishlistRepositoryTest.java index fbe65607f..23e8f5511 100644 --- a/src/test/java/gift/wishlist/WishlistRepositoryTest.java +++ b/src/test/java/gift/wishlist/WishlistRepositoryTest.java @@ -3,6 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import gift.category.CategoryRepository; +import gift.category.Cateogory; import gift.member.Member; import gift.member.MemberRepository; import gift.product.Product; @@ -28,10 +30,20 @@ class WishlistRepositoryTest { @Autowired private MemberRepository memberRepository; + @Autowired + private CategoryRepository categoryRepository; + + @BeforeEach + void setCategoryRepository() { + categoryRepository.save(new Cateogory("교환권","쌈@뽕한 블루","www","여름")); + categoryRepository.save(new Cateogory("과제면제권","방학","www.com","학교")); + categoryRepository.save(new Cateogory("라우브","스틸더","www.show","키야")); + } + @BeforeEach void setProductRepository() { - productRepository.save(new Product("사과", 2000, "www")); - productRepository.save(new Product("바나나", 3000,"www.com")); + productRepository.save(new Product("사과", 2000, "www", categoryRepository.findById(1L).get())); + productRepository.save(new Product("바나나", 3000,"www.com", categoryRepository.findById(2L).get())); } @BeforeEach @@ -47,7 +59,7 @@ void add() { memberRepository.findById(1L).get(), productRepository.findById(1L).get() ); - + Wishlist actual = wishlistRepository.save(expected); assertAll( () -> assertThat(actual).isEqualTo(expected) From a9c47e51ce686bcc6c4cbffc38f73ca02d7ceb0e Mon Sep 17 00:00:00 2001 From: SeoYeongU Date: Thu, 18 Jul 2024 20:15:22 +0900 Subject: [PATCH 8/8] =?UTF-8?q?style:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/gift/category/CategoryRepositoryTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/java/gift/category/CategoryRepositoryTest.java b/src/test/java/gift/category/CategoryRepositoryTest.java index cc5d4640d..252855ada 100644 --- a/src/test/java/gift/category/CategoryRepositoryTest.java +++ b/src/test/java/gift/category/CategoryRepositoryTest.java @@ -31,13 +31,6 @@ void setCategoryRepository() { categoryRepository.save(new Cateogory("라우브","스틸더","www.show","키야")); } -// @BeforeEach -// void setProductRepository() { -// productRepository.save(new Product("사과", 2000, "www",)); -// productRepository.save(new Product("참외",4000,"달다!",1)); -// productRepository.save(new Product("바나나", 3000,"맛있다!",2)); -// } - @Test @DisplayName("카테고리 저장 테스트") void save() {