From 617e5b061cd7eb8cbf5e6bce42f30ec13f29b85b Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Mon, 22 Jul 2024 17:28:22 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=9A=B0=EC=84=A0=EC=88=9C=EC=9C=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tsulocalize --- .../controller/CategoryController.java | 9 +++++ .../category/domain/CategoryPriority.java | 33 +++++++++++++++++++ .../dto/CategoryPriorityCreateRequest.java | 6 ++++ .../CategoryPriorityRepository.java | 9 +++++ .../category/service/CategoryService.java | 26 +++++++++++++++ .../bang_ggood/exception/ExceptionCode.java | 4 ++- .../java/com/bang_ggood/user/domain/User.java | 28 ++++++++++++++++ .../user/repository/UserRepository.java | 15 +++++++++ .../bang-ggood/src/main/resources/data.sql | 2 ++ .../bang-ggood/src/main/resources/schema.sql | 19 +++++++++++ .../category/service/CategoryServiceTest.java | 26 +++++++++++++-- 11 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java create mode 100644 backend/bang-ggood/src/main/java/com/bang_ggood/category/dto/CategoryPriorityCreateRequest.java create mode 100644 backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java create mode 100644 backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java create mode 100644 backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java create mode 100644 backend/bang-ggood/src/main/resources/data.sql create mode 100644 backend/bang-ggood/src/main/resources/schema.sql diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java index 91800937d..b2c2e62d0 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java @@ -1,9 +1,12 @@ package com.bang_ggood.category.controller; import com.bang_ggood.category.dto.CategoriesReadResponse; +import com.bang_ggood.category.dto.CategoryPriorityCreateRequest; import com.bang_ggood.category.service.CategoryService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @@ -15,6 +18,12 @@ public CategoryController(CategoryService categoryService) { this.categoryService = categoryService; } + @PostMapping("/categories/priority") + public ResponseEntity createCategoriesPriority(@RequestBody CategoryPriorityCreateRequest request) { + categoryService.createCategoriesPriority(request); + return ResponseEntity.noContent().build(); + } + @GetMapping("/categories") public ResponseEntity readCategories() { return ResponseEntity.ok(categoryService.readCategories()); diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java new file mode 100644 index 000000000..2ae157565 --- /dev/null +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java @@ -0,0 +1,33 @@ +package com.bang_ggood.category.domain; + +import com.bang_ggood.BaseEntity; +import com.bang_ggood.user.domain.User; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; + +@Entity +public class CategoryPriority extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "category_id") + private Integer categoryId; + + @ManyToOne(fetch = FetchType.LAZY) + private User user; + + protected CategoryPriority() { + } + + public CategoryPriority(Integer categoryId, User user) { + this.categoryId = categoryId; + this.user = user; + } +} diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/dto/CategoryPriorityCreateRequest.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/dto/CategoryPriorityCreateRequest.java new file mode 100644 index 000000000..543324b60 --- /dev/null +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/dto/CategoryPriorityCreateRequest.java @@ -0,0 +1,6 @@ +package com.bang_ggood.category.dto; + +import java.util.List; + +public record CategoryPriorityCreateRequest(List categoryIds) { +} diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java new file mode 100644 index 000000000..68f5da229 --- /dev/null +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java @@ -0,0 +1,9 @@ +package com.bang_ggood.category.repository; + +import com.bang_ggood.category.domain.CategoryPriority; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CategoryPriorityRepository extends JpaRepository { +} diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java index 5bcd37c85..5ea8495dc 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java @@ -1,19 +1,45 @@ package com.bang_ggood.category.service; import com.bang_ggood.category.domain.Category; +import com.bang_ggood.category.domain.CategoryPriority; import com.bang_ggood.category.dto.CategoriesReadResponse; +import com.bang_ggood.category.dto.CategoryPriorityCreateRequest; import com.bang_ggood.category.dto.CategoryReadResponse; +import com.bang_ggood.category.repository.CategoryPriorityRepository; +import com.bang_ggood.user.domain.User; +import com.bang_ggood.user.repository.UserRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.Arrays; import java.util.List; @Service public class CategoryService { + private final CategoryPriorityRepository categoryPriorityRepository; + private final UserRepository userRepository; + + public CategoryService(CategoryPriorityRepository categoryPriorityRepository, UserRepository userRepository) { + this.categoryPriorityRepository = categoryPriorityRepository; + this.userRepository = userRepository; + } + + @Transactional + public void createCategoriesPriority(CategoryPriorityCreateRequest request) { + User user = userRepository.getUserById(1L); + List categoryPriorities = request.categoryIds().stream() + .map(id -> new CategoryPriority(id, user)) + .toList(); + + categoryPriorityRepository.saveAll(categoryPriorities); + } + public CategoriesReadResponse readCategories() { List categoryReadResponses = Arrays.stream(Category.values()) .map(CategoryReadResponse::from) .toList(); return new CategoriesReadResponse(categoryReadResponses); } + + } diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java b/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java index 51ddfe69b..9b8c71094 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java @@ -4,7 +4,9 @@ public enum ExceptionCode { - INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 인자입니다."); + INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 인자입니다."), + USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "유저가 존재하지 않습니다."), + ; private final HttpStatus httpStatus; private final String message; diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java b/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java new file mode 100644 index 000000000..bd0d4df01 --- /dev/null +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java @@ -0,0 +1,28 @@ +package com.bang_ggood.user.domain; + +import com.bang_ggood.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Table(name = "users") +@Entity +public class User extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String name; + + protected User() { + } + + public User(String name) { + this.name = name; + } +} diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java b/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java new file mode 100644 index 000000000..96b32288e --- /dev/null +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java @@ -0,0 +1,15 @@ +package com.bang_ggood.user.repository; + +import com.bang_ggood.exception.BangggoodException; +import com.bang_ggood.exception.ExceptionCode; +import com.bang_ggood.user.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends JpaRepository { + + default User getUserById(Long id) { + return findById(id).orElseThrow(() -> new BangggoodException(ExceptionCode.USER_NOT_FOUND)); + } +} diff --git a/backend/bang-ggood/src/main/resources/data.sql b/backend/bang-ggood/src/main/resources/data.sql new file mode 100644 index 000000000..31aaed9e4 --- /dev/null +++ b/backend/bang-ggood/src/main/resources/data.sql @@ -0,0 +1,2 @@ +INSERT INTO users(id, name, created_at, modified_at) +VALUES (1, '방방이', '2024-07-22 07:56:42', '2024-07-22 07:56:42'); diff --git a/backend/bang-ggood/src/main/resources/schema.sql b/backend/bang-ggood/src/main/resources/schema.sql new file mode 100644 index 000000000..a318875f2 --- /dev/null +++ b/backend/bang-ggood/src/main/resources/schema.sql @@ -0,0 +1,19 @@ +CREATE TABLE users +( + id bigint generated by default as identity, + name varchar(255) not null, + created_at TIMESTAMP not null, + modified_at TIMESTAMP not null, + primary key (id) +); + +CREATE TABLE category_priority +( + id bigint generated by default as identity, + category_id tinyint not null, + user_id bigint not null, + created_at TIMESTAMP not null, + modified_at TIMESTAMP not null, + primary key (id), + foreign key (user_id) references users +); diff --git a/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java b/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java index c4155d48b..7bd9243d8 100644 --- a/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java +++ b/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java @@ -1,13 +1,19 @@ package com.bang_ggood.category.service; -import com.bang_ggood.category.domain.Category; import com.bang_ggood.category.dto.CategoriesReadResponse; +import com.bang_ggood.category.dto.CategoryPriorityCreateRequest; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import java.util.List; + +import static com.bang_ggood.category.domain.Category.AMENITY; +import static com.bang_ggood.category.domain.Category.CLEAN; +import static com.bang_ggood.category.domain.Category.ECONOMIC; +import static com.bang_ggood.category.domain.Category.values; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class CategoryServiceTest { @@ -15,6 +21,22 @@ class CategoryServiceTest { @Autowired private CategoryService categoryService; + @DisplayName("카테고리 우선순위 생성 성공") + @Test + void createCategoriesPriority() { + // given + CategoryPriorityCreateRequest request = new CategoryPriorityCreateRequest(List.of( + CLEAN.getId(), + AMENITY.getId(), + ECONOMIC.getId() + )); + + // when & then + Assertions.assertThatCode(() -> categoryService.createCategoriesPriority(request)) + .doesNotThrowAnyException(); + // TODO: 추후 예외 처리 예정 + } + @DisplayName("카테고리 조회 성공") @Test void readCategories() { @@ -23,6 +45,6 @@ void readCategories() { // then Assertions.assertThat(categoriesReadResponse.categories()) - .hasSize(Category.values().length); + .hasSize(values().length); } } From dcc317aa8be663527dd5e346b2581045915206dc Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Tue, 23 Jul 2024 10:24:49 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EC=9A=B0=EC=84=A0=EC=88=9C=EC=9C=84=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EA=B4=80=EB=A0=A8=20=EA=B2=80=EC=A6=9D=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bang_ggood/category/domain/Category.java | 7 ++ .../category/service/CategoryService.java | 34 +++++++++- .../bang_ggood/exception/ExceptionCode.java | 3 + .../java/com/bang_ggood/JpaAuditingTest.java | 4 ++ .../category/service/CategoryServiceTest.java | 66 +++++++++++++++++-- .../src/test/resources/application-test.yml | 20 ++++++ .../src/test/resources/data-test.sql | 2 + .../src/test/resources/schema-test.sql | 30 +++++++++ 8 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 backend/bang-ggood/src/test/resources/application-test.yml create mode 100644 backend/bang-ggood/src/test/resources/data-test.sql create mode 100644 backend/bang-ggood/src/test/resources/schema-test.sql diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java index eb04b3e9b..5cd1ea368 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java @@ -1,5 +1,7 @@ package com.bang_ggood.category.domain; +import java.util.Arrays; + public enum Category { CLEAN(1, "청결"), @@ -18,6 +20,11 @@ public enum Category { this.description = description; } + public static boolean contains(Integer id) { + return Arrays.stream(values()) + .anyMatch(category -> category.id.equals(id)); + } + public Integer getId() { return id; } diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java index 5ea8495dc..c588d7bff 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/service/CategoryService.java @@ -6,16 +6,24 @@ import com.bang_ggood.category.dto.CategoryPriorityCreateRequest; import com.bang_ggood.category.dto.CategoryReadResponse; import com.bang_ggood.category.repository.CategoryPriorityRepository; +import com.bang_ggood.exception.BangggoodException; import com.bang_ggood.user.domain.User; import com.bang_ggood.user.repository.UserRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Arrays; import java.util.List; +import java.util.Set; + +import static com.bang_ggood.exception.ExceptionCode.CATEGORY_DUPLICATED; +import static com.bang_ggood.exception.ExceptionCode.CATEGORY_NOT_FOUND; +import static com.bang_ggood.exception.ExceptionCode.CATEGORY_PRIORITY_INVALID_COUNT; @Service public class CategoryService { + private static final int MAX_CATEGORY_PRIORITY_COUNT = 3; + private final CategoryPriorityRepository categoryPriorityRepository; private final UserRepository userRepository; @@ -26,6 +34,10 @@ public CategoryService(CategoryPriorityRepository categoryPriorityRepository, Us @Transactional public void createCategoriesPriority(CategoryPriorityCreateRequest request) { + validateDuplication(request); + validateCategoryCount(request); + validateCategoryId(request); + User user = userRepository.getUserById(1L); List categoryPriorities = request.categoryIds().stream() .map(id -> new CategoryPriority(id, user)) @@ -34,12 +46,30 @@ public void createCategoriesPriority(CategoryPriorityCreateRequest request) { categoryPriorityRepository.saveAll(categoryPriorities); } + private void validateDuplication(CategoryPriorityCreateRequest request) { + if (request.categoryIds().size() != Set.copyOf(request.categoryIds()).size()) { + throw new BangggoodException(CATEGORY_DUPLICATED); + } + } + + private void validateCategoryCount(CategoryPriorityCreateRequest request) { + if (request.categoryIds().size() > MAX_CATEGORY_PRIORITY_COUNT) { + throw new BangggoodException(CATEGORY_PRIORITY_INVALID_COUNT); + } + } + + private void validateCategoryId(CategoryPriorityCreateRequest request) { + for (Integer id : request.categoryIds()) { + if (!Category.contains(id)) { + throw new BangggoodException(CATEGORY_NOT_FOUND); + } + } + } + public CategoriesReadResponse readCategories() { List categoryReadResponses = Arrays.stream(Category.values()) .map(CategoryReadResponse::from) .toList(); return new CategoriesReadResponse(categoryReadResponses); } - - } diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java b/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java index 9b8c71094..6caa1dcb0 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/exception/ExceptionCode.java @@ -6,6 +6,9 @@ public enum ExceptionCode { INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "잘못된 인자입니다."), USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "유저가 존재하지 않습니다."), + CATEGORY_PRIORITY_INVALID_COUNT(HttpStatus.BAD_REQUEST, "카테고리 개수가 유효하지 않습니다."), + CATEGORY_NOT_FOUND(HttpStatus.BAD_REQUEST, "카테코리가 존재하지 않습니다."), + CATEGORY_DUPLICATED(HttpStatus.BAD_REQUEST, "중복된 카테고리가 존재합니다."), ; private final HttpStatus httpStatus; diff --git a/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java b/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java index a484db970..0c2a36487 100644 --- a/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java +++ b/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java @@ -4,17 +4,20 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.Table; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; import java.time.LocalDateTime; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +@ActiveProfiles("test") @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) class JpaAuditingTest { @@ -56,6 +59,7 @@ void jpaAuditing_modifyEntity() { ); } + @Table(name = "test_entity") @Entity static class TestEntity extends BaseEntity { diff --git a/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java b/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java index 7bd9243d8..3af2f0171 100644 --- a/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java +++ b/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java @@ -2,20 +2,29 @@ import com.bang_ggood.category.dto.CategoriesReadResponse; import com.bang_ggood.category.dto.CategoryPriorityCreateRequest; -import org.assertj.core.api.Assertions; +import com.bang_ggood.exception.BangggoodException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.ActiveProfiles; import java.util.List; import static com.bang_ggood.category.domain.Category.AMENITY; import static com.bang_ggood.category.domain.Category.CLEAN; import static com.bang_ggood.category.domain.Category.ECONOMIC; +import static com.bang_ggood.category.domain.Category.SECURITY; import static com.bang_ggood.category.domain.Category.values; +import static com.bang_ggood.exception.ExceptionCode.CATEGORY_DUPLICATED; +import static com.bang_ggood.exception.ExceptionCode.CATEGORY_NOT_FOUND; +import static com.bang_ggood.exception.ExceptionCode.CATEGORY_PRIORITY_INVALID_COUNT; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") class CategoryServiceTest { @Autowired @@ -32,9 +41,58 @@ void createCategoriesPriority() { )); // when & then - Assertions.assertThatCode(() -> categoryService.createCategoriesPriority(request)) + assertThatCode(() -> categoryService.createCategoriesPriority(request)) .doesNotThrowAnyException(); - // TODO: 추후 예외 처리 예정 + // TODO: 추후 우선순위 조회 API로 예외 검증 + } + + @DisplayName("카테고리 우선순위 생성 실패 : 카테고리 개수가 유효하지 않을 때") + @Test + void createCategoriesPriority_invalidCount_exception() { + // given + CategoryPriorityCreateRequest request = new CategoryPriorityCreateRequest(List.of( + CLEAN.getId(), + AMENITY.getId(), + ECONOMIC.getId(), + SECURITY.getId() + )); + + // when & then + assertThatThrownBy(() -> categoryService.createCategoriesPriority(request)) + .isInstanceOf(BangggoodException.class) + .hasMessage(CATEGORY_PRIORITY_INVALID_COUNT.getMessage()); + } + + @DisplayName("카테고리 우선순위 생성 실패 : 카테고리가 존재하지 않을 때") + @Test + void createCategoriesPriority_notFound_exception() { + // given + CategoryPriorityCreateRequest request = new CategoryPriorityCreateRequest(List.of( + CLEAN.getId(), + AMENITY.getId(), + 0 + )); + + // when & then + assertThatThrownBy(() -> categoryService.createCategoriesPriority(request)) + .isInstanceOf(BangggoodException.class) + .hasMessage(CATEGORY_NOT_FOUND.getMessage()); + } + + @DisplayName("카테고리 우선순위 생성 실패 : 중복된 카테고리가 존재할 때") + @Test + void createCategoriesPriority_duplicated_exception() { + // given + CategoryPriorityCreateRequest request = new CategoryPriorityCreateRequest(List.of( + CLEAN.getId(), + AMENITY.getId(), + AMENITY.getId() + )); + + // when & then + assertThatThrownBy(() -> categoryService.createCategoriesPriority(request)) + .isInstanceOf(BangggoodException.class) + .hasMessage(CATEGORY_DUPLICATED.getMessage()); } @DisplayName("카테고리 조회 성공") @@ -44,7 +102,7 @@ void readCategories() { CategoriesReadResponse categoriesReadResponse = categoryService.readCategories(); // then - Assertions.assertThat(categoriesReadResponse.categories()) + assertThat(categoriesReadResponse.categories()) .hasSize(values().length); } } diff --git a/backend/bang-ggood/src/test/resources/application-test.yml b/backend/bang-ggood/src/test/resources/application-test.yml new file mode 100644 index 000000000..ded52afaa --- /dev/null +++ b/backend/bang-ggood/src/test/resources/application-test.yml @@ -0,0 +1,20 @@ +spring: + h2: + console: + enabled: true + datasource: + url: jdbc:h2:mem:database + username: bang-ggood + password: 608bang-ggood-dev + driverClassName: org.h2.Driver + jpa: + defer-datasource-initialization: true + open-in-view: false + show-sql: true + hibernate: + ddl-auto: none + + sql: + init: + schema-locations: classpath:schema-test.sql + data-locations: classpath:data-test.sql diff --git a/backend/bang-ggood/src/test/resources/data-test.sql b/backend/bang-ggood/src/test/resources/data-test.sql new file mode 100644 index 000000000..31aaed9e4 --- /dev/null +++ b/backend/bang-ggood/src/test/resources/data-test.sql @@ -0,0 +1,2 @@ +INSERT INTO users(id, name, created_at, modified_at) +VALUES (1, '방방이', '2024-07-22 07:56:42', '2024-07-22 07:56:42'); diff --git a/backend/bang-ggood/src/test/resources/schema-test.sql b/backend/bang-ggood/src/test/resources/schema-test.sql new file mode 100644 index 000000000..a4583caf7 --- /dev/null +++ b/backend/bang-ggood/src/test/resources/schema-test.sql @@ -0,0 +1,30 @@ +CREATE TABLE if not exists users +( + id bigint generated by default as identity, + name varchar(255) not null, + created_at TIMESTAMP not null, + modified_at TIMESTAMP not null, + primary key (id) +); + +CREATE TABLE if not exists category_priority +( + id bigint generated by default as identity, + category_id tinyint not null, + user_id bigint not null, + created_at TIMESTAMP not null, + modified_at TIMESTAMP not null, + primary key (id), + foreign key (user_id) references users +); + + +CREATE TABLE test_entity +( + id bigint generated by default as identity, + name varchar(255) not null, + created_at TIMESTAMP not null, + modified_at TIMESTAMP not null, + primary key (id) +); + From a63b7273fb09a6e8b24acd783a51726aa62975a9 Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Tue, 23 Jul 2024 13:29:32 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor:=20IntegrationTestSupport=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/bang-ggood/.gitignore | 1 + .../bang_ggood/IntegrationTestSupport.java | 11 ++++++++++ .../java/com/bang_ggood/JpaAuditingTest.java | 9 +-------- .../category/service/CategoryServiceTest.java | 8 ++------ .../src/test/resources/application-test.yml | 20 ------------------- 5 files changed, 15 insertions(+), 34 deletions(-) create mode 100644 backend/bang-ggood/src/test/java/com/bang_ggood/IntegrationTestSupport.java delete mode 100644 backend/bang-ggood/src/test/resources/application-test.yml diff --git a/backend/bang-ggood/.gitignore b/backend/bang-ggood/.gitignore index 06da7f656..cb8bf25be 100644 --- a/backend/bang-ggood/.gitignore +++ b/backend/bang-ggood/.gitignore @@ -19,6 +19,7 @@ bin/ ### IntelliJ IDEA ### src/main/resources/application.yml +src/test/resources/application-test.yml .idea *.iws *.iml diff --git a/backend/bang-ggood/src/test/java/com/bang_ggood/IntegrationTestSupport.java b/backend/bang-ggood/src/test/java/com/bang_ggood/IntegrationTestSupport.java new file mode 100644 index 000000000..903186620 --- /dev/null +++ b/backend/bang-ggood/src/test/java/com/bang_ggood/IntegrationTestSupport.java @@ -0,0 +1,11 @@ +package com.bang_ggood; + + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.ActiveProfiles; + +@ActiveProfiles("test") +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public abstract class IntegrationTestSupport { +} diff --git a/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java b/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java index 0c2a36487..f2b231d7c 100644 --- a/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java +++ b/backend/bang-ggood/src/test/java/com/bang_ggood/JpaAuditingTest.java @@ -8,19 +8,12 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; import java.time.LocalDateTime; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -@ActiveProfiles("test") -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -class JpaAuditingTest { +class JpaAuditingTest extends IntegrationTestSupport{ @Autowired private TestRepository testRepository; diff --git a/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java b/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java index 3af2f0171..5ed9a9f46 100644 --- a/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java +++ b/backend/bang-ggood/src/test/java/com/bang_ggood/category/service/CategoryServiceTest.java @@ -1,14 +1,12 @@ package com.bang_ggood.category.service; +import com.bang_ggood.IntegrationTestSupport; import com.bang_ggood.category.dto.CategoriesReadResponse; import com.bang_ggood.category.dto.CategoryPriorityCreateRequest; import com.bang_ggood.exception.BangggoodException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.test.context.ActiveProfiles; import java.util.List; import static com.bang_ggood.category.domain.Category.AMENITY; @@ -23,9 +21,7 @@ import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@ActiveProfiles("test") -class CategoryServiceTest { +class CategoryServiceTest extends IntegrationTestSupport { @Autowired private CategoryService categoryService; diff --git a/backend/bang-ggood/src/test/resources/application-test.yml b/backend/bang-ggood/src/test/resources/application-test.yml deleted file mode 100644 index ded52afaa..000000000 --- a/backend/bang-ggood/src/test/resources/application-test.yml +++ /dev/null @@ -1,20 +0,0 @@ -spring: - h2: - console: - enabled: true - datasource: - url: jdbc:h2:mem:database - username: bang-ggood - password: 608bang-ggood-dev - driverClassName: org.h2.Driver - jpa: - defer-datasource-initialization: true - open-in-view: false - show-sql: true - hibernate: - ddl-auto: none - - sql: - init: - schema-locations: classpath:schema-test.sql - data-locations: classpath:data-test.sql From 23145e64698efa6e23ce4dd3cf75feacc5105534 Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Tue, 23 Jul 2024 13:43:15 +0900 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=EB=94=94=20=ED=83=80=EC=9E=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EB=AC=B8?= =?UTF-8?q?=EB=B2=95=20=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tsulocalize --- .../src/main/java/com/bang_ggood/category/domain/Category.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java index 17de1441a..58386358b 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java @@ -22,7 +22,7 @@ public enum Category { public static boolean contains(Integer id) { return Arrays.stream(values()) - .anyMatch(category -> category.id.equals(id)); + .anyMatch(category -> category.id == id); } public int getId() { From 241ec7426c18dda3fcdff4745b9f6c421ff301d3 Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Tue, 23 Jul 2024 16:32:36 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20id=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD(Integer=20->=20int)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tsulocalize --- .../com/bang_ggood/category/controller/CategoryController.java | 1 + .../src/main/java/com/bang_ggood/category/domain/Category.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java index b2c2e62d0..bfc0669b2 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/controller/CategoryController.java @@ -20,6 +20,7 @@ public CategoryController(CategoryService categoryService) { @PostMapping("/categories/priority") public ResponseEntity createCategoriesPriority(@RequestBody CategoryPriorityCreateRequest request) { + // TODO: List 요소 null check 필요 categoryService.createCategoriesPriority(request); return ResponseEntity.noContent().build(); } diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java index 58386358b..14f547670 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/Category.java @@ -20,7 +20,7 @@ public enum Category { this.description = description; } - public static boolean contains(Integer id) { + public static boolean contains(int id) { return Arrays.stream(values()) .anyMatch(category -> category.id == id); } From 65c314204d7862ebe390adf73f82daf5685abbfe Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Tue, 23 Jul 2024 16:33:24 +0900 Subject: [PATCH 6/7] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20@Repository=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tsulocalize --- .../category/repository/CategoryPriorityRepository.java | 2 -- .../java/com/bang_ggood/user/repository/UserRepository.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java index 68f5da229..d37dda882 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/repository/CategoryPriorityRepository.java @@ -2,8 +2,6 @@ import com.bang_ggood.category.domain.CategoryPriority; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -@Repository public interface CategoryPriorityRepository extends JpaRepository { } diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java b/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java index 96b32288e..65cadda49 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/user/repository/UserRepository.java @@ -4,9 +4,7 @@ import com.bang_ggood.exception.ExceptionCode; import com.bang_ggood.user.domain.User; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -@Repository public interface UserRepository extends JpaRepository { default User getUserById(Long id) { From d1f610acda8e185614ca82c74286fc5970628ff3 Mon Sep 17 00:00:00 2001 From: jinwoo22 Date: Tue, 23 Jul 2024 16:34:05 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20domain=20equals,=20hashcode,=20toSt?= =?UTF-8?q?ring=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9E=AC=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tsulocalize --- .../category/domain/CategoryPriority.java | 29 ++++++++++++++++++- .../java/com/bang_ggood/user/domain/User.java | 26 +++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java index 2ae157565..cdd36c60f 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/category/domain/CategoryPriority.java @@ -9,6 +9,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; +import java.util.Objects; @Entity public class CategoryPriority extends BaseEntity { @@ -17,7 +18,7 @@ public class CategoryPriority extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "category_id") + @Column(nullable = false) private Integer categoryId; @ManyToOne(fetch = FetchType.LAZY) @@ -30,4 +31,30 @@ public CategoryPriority(Integer categoryId, User user) { this.categoryId = categoryId; this.user = user; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CategoryPriority that = (CategoryPriority) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "CategoryPriority{" + + "id=" + id + + ", categoryId=" + categoryId + + ", user=" + user + + '}'; + } } diff --git a/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java b/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java index bd0d4df01..a5796317c 100644 --- a/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java +++ b/backend/bang-ggood/src/main/java/com/bang_ggood/user/domain/User.java @@ -7,6 +7,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; +import java.util.Objects; @Table(name = "users") @Entity @@ -25,4 +26,29 @@ protected User() { public User(String name) { this.name = name; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } }