diff --git a/src/main/java/taco/klkl/domain/category/controller/category/CategoryController.java b/src/main/java/taco/klkl/domain/category/controller/category/CategoryController.java index 74bf3ec9..9725c0e4 100644 --- a/src/main/java/taco/klkl/domain/category/controller/category/CategoryController.java +++ b/src/main/java/taco/klkl/domain/category/controller/category/CategoryController.java @@ -23,15 +23,9 @@ public class CategoryController { private final CategoryService categoryService; - @GetMapping - @Operation(summary = "전체 카테고리 목록 조회", description = "전체 카테고리 목록을 조회합니다.") - public List findAllCategories() { + @GetMapping("/hierarchy") + @Operation(summary = "전체 분류의 계층 정보 조회", description = "전체 분류의 계층 정보를 조회합니다.") + public List getAllCategories() { return categoryService.findAllCategories(); } - - @GetMapping("/{categoryId}/subcategories") - @Operation(summary = "대분류의 소분류 목록 조회", description = "Category에 포함된 Subcategory 반환") - public CategoryResponse findSubCategoriesByCategoryId(@PathVariable Long categoryId) { - return categoryService.findSubCategoriesByCategoryId(categoryId); - } } diff --git a/src/main/java/taco/klkl/domain/category/controller/subcategory/SubcategoryController.java b/src/main/java/taco/klkl/domain/category/controller/subcategory/SubcategoryController.java new file mode 100644 index 00000000..7e339c84 --- /dev/null +++ b/src/main/java/taco/klkl/domain/category/controller/subcategory/SubcategoryController.java @@ -0,0 +1,29 @@ +package taco.klkl.domain.category.controller.subcategory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +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 lombok.extern.slf4j.Slf4j; +import taco.klkl.domain.category.dto.response.subcategory.SubcategoryHierarchyResponse; +import taco.klkl.domain.category.service.subcategory.SubcategoryService; + +@Slf4j +@RestController +@Tag(name = "6. 카테고리", description = "카테고리 관련 API") +@RequestMapping("/v1/subcategories") +@RequiredArgsConstructor +public class SubcategoryController { + + private final SubcategoryService subcategoryService; + + @GetMapping("/{subcategoryId}/hierarchy") + @Operation(summary = "특정 소분류의 계층 정보 조회", description = "특정 소분류의 계층 정보를 조회합니다.") + public SubcategoryHierarchyResponse getSubcategoryHierarchy(@PathVariable final Long subcategoryId) { + return subcategoryService.findSubcategoryHierarchyById(subcategoryId); + } +} diff --git a/src/main/java/taco/klkl/domain/category/controller/tag/TagController.java b/src/main/java/taco/klkl/domain/category/controller/tag/TagController.java deleted file mode 100644 index 372c9f9c..00000000 --- a/src/main/java/taco/klkl/domain/category/controller/tag/TagController.java +++ /dev/null @@ -1,37 +0,0 @@ -package taco.klkl.domain.category.controller.tag; - -import java.util.List; -import java.util.Set; - -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 lombok.extern.slf4j.Slf4j; -import taco.klkl.domain.category.domain.subcategory.Subcategory; -import taco.klkl.domain.category.dto.response.tag.TagResponse; -import taco.klkl.domain.category.service.SubcategoryTagService; -import taco.klkl.domain.category.service.subcategory.SubcategoryService; - -@Slf4j -@Tag(name = "6. 카테고리", description = "카테고리 관련 API") -@RestController -@RequestMapping("/v1/tags") -@RequiredArgsConstructor -public class TagController { - private final SubcategoryService subcategoryService; - private final SubcategoryTagService subcategoryTagService; - - @GetMapping - @Operation(summary = "선택된 소분류의 태그 목록 조회", description = "선택된 소분류의 태그 목록을 조회합니다.") - public Set findAllTagsBySubcategoryIds( - @RequestParam(value = "subcategory_id") final List subcategoryIds - ) { - final List subcategoryList = subcategoryService.findSubcategoriesBySubcategoryIds(subcategoryIds); - return subcategoryTagService.findTagsBySubcategoryList(subcategoryList); - } -} diff --git a/src/main/java/taco/klkl/domain/category/domain/category/Category.java b/src/main/java/taco/klkl/domain/category/domain/category/Category.java index 62224662..8b2677e5 100644 --- a/src/main/java/taco/klkl/domain/category/domain/category/Category.java +++ b/src/main/java/taco/klkl/domain/category/domain/category/Category.java @@ -9,6 +9,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,6 +20,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Category { + @Transient private CategoryType categoryType; @Id diff --git a/src/main/java/taco/klkl/domain/category/domain/subcategory/Subcategory.java b/src/main/java/taco/klkl/domain/category/domain/subcategory/Subcategory.java index 4d6871b4..d782c52d 100644 --- a/src/main/java/taco/klkl/domain/category/domain/subcategory/Subcategory.java +++ b/src/main/java/taco/klkl/domain/category/domain/subcategory/Subcategory.java @@ -12,6 +12,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -23,6 +24,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Subcategory { + @Transient private SubcategoryType subcategoryType; @Id diff --git a/src/main/java/taco/klkl/domain/category/domain/tag/Tag.java b/src/main/java/taco/klkl/domain/category/domain/tag/Tag.java index 34e3e116..5a198155 100644 --- a/src/main/java/taco/klkl/domain/category/domain/tag/Tag.java +++ b/src/main/java/taco/klkl/domain/category/domain/tag/Tag.java @@ -11,6 +11,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -22,6 +23,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Tag { + @Transient private TagType tagType; @Id diff --git a/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryHierarchyResponse.java b/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryHierarchyResponse.java new file mode 100644 index 00000000..1a1be868 --- /dev/null +++ b/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryHierarchyResponse.java @@ -0,0 +1,18 @@ +package taco.klkl.domain.category.dto.response.subcategory; + +import taco.klkl.domain.category.domain.category.Category; +import taco.klkl.domain.category.domain.subcategory.Subcategory; + +public record SubcategoryHierarchyResponse( + Long subcategoryId, + Long categoryId +) { + public static SubcategoryHierarchyResponse from(final Subcategory subcategory) { + final Category category = subcategory.getCategory(); + + return new SubcategoryHierarchyResponse( + subcategory.getId(), + category.getId() + ); + } +} diff --git a/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryResponse.java b/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryResponse.java index 774409d6..5b38e248 100644 --- a/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryResponse.java +++ b/src/main/java/taco/klkl/domain/category/dto/response/subcategory/SubcategoryResponse.java @@ -1,12 +1,26 @@ package taco.klkl.domain.category.dto.response.subcategory; +import java.util.List; + +import taco.klkl.domain.category.domain.SubcategoryTag; import taco.klkl.domain.category.domain.subcategory.Subcategory; +import taco.klkl.domain.category.dto.response.tag.TagResponse; public record SubcategoryResponse( Long id, - String name + String name, + List tags ) { public static SubcategoryResponse from(final Subcategory subcategory) { - return new SubcategoryResponse(subcategory.getId(), subcategory.getName()); + final List tags = subcategory.getSubcategoryTags().stream() + .map(SubcategoryTag::getTag) + .map(TagResponse::from) + .toList(); + + return new SubcategoryResponse( + subcategory.getId(), + subcategory.getName(), + tags + ); } } diff --git a/src/main/java/taco/klkl/domain/category/service/SubcategoryTagService.java b/src/main/java/taco/klkl/domain/category/service/SubcategoryTagService.java deleted file mode 100644 index 195e60b9..00000000 --- a/src/main/java/taco/klkl/domain/category/service/SubcategoryTagService.java +++ /dev/null @@ -1,16 +0,0 @@ -package taco.klkl.domain.category.service; - -import java.util.List; -import java.util.Set; - -import org.springframework.stereotype.Service; - -import taco.klkl.domain.category.domain.subcategory.Subcategory; -import taco.klkl.domain.category.dto.response.tag.TagResponse; - -@Service -public interface SubcategoryTagService { - - Set findTagsBySubcategoryList(final List subcategoryList); - -} diff --git a/src/main/java/taco/klkl/domain/category/service/SubcategoryTagServiceImpl.java b/src/main/java/taco/klkl/domain/category/service/SubcategoryTagServiceImpl.java deleted file mode 100644 index 519a31d3..00000000 --- a/src/main/java/taco/klkl/domain/category/service/SubcategoryTagServiceImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -package taco.klkl.domain.category.service; - -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import taco.klkl.domain.category.dao.SubcategoryTagRepository; -import taco.klkl.domain.category.domain.SubcategoryTag; -import taco.klkl.domain.category.domain.subcategory.Subcategory; -import taco.klkl.domain.category.dto.response.tag.TagResponse; - -@Slf4j -@Primary -@Service -@Transactional(readOnly = true) -@RequiredArgsConstructor -public class SubcategoryTagServiceImpl implements SubcategoryTagService { - - private final SubcategoryTagRepository subcategoryTagRepository; - - @Override - public Set findTagsBySubcategoryList( - final List subcategoryList - ) { - return subcategoryList.stream() - .map(subcategoryTagRepository::findAllBySubcategory) - .flatMap(Collection::stream) - .map(SubcategoryTag::getTag) - .map(TagResponse::from) - .collect(Collectors.toSet()); - } -} diff --git a/src/main/java/taco/klkl/domain/category/service/category/CategoryService.java b/src/main/java/taco/klkl/domain/category/service/category/CategoryService.java index 64219b75..cbf963ed 100644 --- a/src/main/java/taco/klkl/domain/category/service/category/CategoryService.java +++ b/src/main/java/taco/klkl/domain/category/service/category/CategoryService.java @@ -11,7 +11,5 @@ public interface CategoryService { List findAllCategories(); - CategoryResponse findSubCategoriesByCategoryId(final Long categoryId); - List findAllCategoriesByPartialString(final String partialString); } diff --git a/src/main/java/taco/klkl/domain/category/service/category/CategoryServiceImpl.java b/src/main/java/taco/klkl/domain/category/service/category/CategoryServiceImpl.java index 6baf2b0b..dacbbc01 100644 --- a/src/main/java/taco/klkl/domain/category/service/category/CategoryServiceImpl.java +++ b/src/main/java/taco/klkl/domain/category/service/category/CategoryServiceImpl.java @@ -30,13 +30,6 @@ public List findAllCategories() { .toList(); } - @Override - public CategoryResponse findSubCategoriesByCategoryId(final Long categoryId) { - final Category category = categoryRepository.findById(categoryId) - .orElseThrow(CategoryNotFoundException::new); - return CategoryResponse.from(category); - } - @Override public List findAllCategoriesByPartialString(final String partialString) { if (partialString == null || partialString.isEmpty()) { diff --git a/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryService.java b/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryService.java index aa479b82..b8e2efad 100644 --- a/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryService.java +++ b/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryService.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Service; import taco.klkl.domain.category.domain.subcategory.Subcategory; +import taco.klkl.domain.category.dto.response.subcategory.SubcategoryHierarchyResponse; import taco.klkl.domain.category.dto.response.subcategory.SubcategoryResponse; @Service @@ -12,5 +13,5 @@ public interface SubcategoryService { List findAllSubcategoriesByPartialString(final String partialString); - List findSubcategoriesBySubcategoryIds(final List subcategoryIds); + SubcategoryHierarchyResponse findSubcategoryHierarchyById(final Long id); } diff --git a/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImpl.java b/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImpl.java index 75408dbd..442205bf 100644 --- a/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImpl.java +++ b/src/main/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImpl.java @@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import taco.klkl.domain.category.dao.subcategory.SubcategoryRepository; import taco.klkl.domain.category.domain.subcategory.Subcategory; +import taco.klkl.domain.category.dto.response.subcategory.SubcategoryHierarchyResponse; import taco.klkl.domain.category.dto.response.subcategory.SubcategoryResponse; import taco.klkl.domain.category.exception.subcategory.SubcategoryNotFoundException; @@ -34,15 +35,9 @@ public List findAllSubcategoriesByPartialString(final Strin } @Override - public List findSubcategoriesBySubcategoryIds(final List subcategoryIds) { - final List subcategories = subcategoryRepository.findAllById(subcategoryIds); - validateSubcategories(subcategoryIds.size(), subcategories.size()); - return subcategories; - } - - private void validateSubcategories(final int request, final int result) { - if (request != result) { - throw new SubcategoryNotFoundException(); - } + public SubcategoryHierarchyResponse findSubcategoryHierarchyById(final Long id) { + final Subcategory subcategory = subcategoryRepository.findById(id) + .orElseThrow(SubcategoryNotFoundException::new); + return SubcategoryHierarchyResponse.from(subcategory); } } diff --git a/src/main/java/taco/klkl/domain/comment/dao/CommentRepository.java b/src/main/java/taco/klkl/domain/comment/dao/CommentRepository.java index 4ed92eb6..05646566 100644 --- a/src/main/java/taco/klkl/domain/comment/dao/CommentRepository.java +++ b/src/main/java/taco/klkl/domain/comment/dao/CommentRepository.java @@ -7,5 +7,5 @@ import taco.klkl.domain.comment.domain.Comment; public interface CommentRepository extends JpaRepository { - List findAllByProduct_Id(Long productId); + List findByProductIdOrderByCreatedAtDesc(final Long productId); } diff --git a/src/main/java/taco/klkl/domain/comment/dto/response/CommentNotificationResponse.java b/src/main/java/taco/klkl/domain/comment/dto/response/CommentNotificationResponse.java index 94e74eed..fae35a75 100644 --- a/src/main/java/taco/klkl/domain/comment/dto/response/CommentNotificationResponse.java +++ b/src/main/java/taco/klkl/domain/comment/dto/response/CommentNotificationResponse.java @@ -2,12 +2,15 @@ import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; + import taco.klkl.domain.comment.domain.Comment; +import taco.klkl.global.common.constants.DefaultConstants; public record CommentNotificationResponse( String userName, String content, - LocalDateTime createdAt + @JsonFormat(pattern = DefaultConstants.DEFAULT_DATETIME_FORMAT) LocalDateTime createdAt ) { public static CommentNotificationResponse from(final Comment comment) { return new CommentNotificationResponse( diff --git a/src/main/java/taco/klkl/domain/comment/dto/response/CommentResponse.java b/src/main/java/taco/klkl/domain/comment/dto/response/CommentResponse.java index b2b25a18..e3469231 100644 --- a/src/main/java/taco/klkl/domain/comment/dto/response/CommentResponse.java +++ b/src/main/java/taco/klkl/domain/comment/dto/response/CommentResponse.java @@ -2,14 +2,17 @@ import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; + import taco.klkl.domain.comment.domain.Comment; import taco.klkl.domain.user.dto.response.UserSimpleResponse; +import taco.klkl.global.common.constants.DefaultConstants; public record CommentResponse( Long id, UserSimpleResponse user, String content, - LocalDateTime createdAt + @JsonFormat(pattern = DefaultConstants.DEFAULT_DATETIME_FORMAT) LocalDateTime createdAt ) { public static CommentResponse from(final Comment comment) { return new CommentResponse( diff --git a/src/main/java/taco/klkl/domain/comment/exception/CommentProductNotMatch.java b/src/main/java/taco/klkl/domain/comment/exception/CommentProductNotMatchException.java similarity index 64% rename from src/main/java/taco/klkl/domain/comment/exception/CommentProductNotMatch.java rename to src/main/java/taco/klkl/domain/comment/exception/CommentProductNotMatchException.java index c3c71701..ce62777b 100644 --- a/src/main/java/taco/klkl/domain/comment/exception/CommentProductNotMatch.java +++ b/src/main/java/taco/klkl/domain/comment/exception/CommentProductNotMatchException.java @@ -3,8 +3,8 @@ import taco.klkl.global.error.exception.CustomException; import taco.klkl.global.error.exception.ErrorCode; -public class CommentProductNotMatch extends CustomException { - public CommentProductNotMatch() { +public class CommentProductNotMatchException extends CustomException { + public CommentProductNotMatchException() { super(ErrorCode.COMMENT_PRODUCT_NOT_MATCH); } } diff --git a/src/main/java/taco/klkl/domain/comment/exception/CommentUserNotMatchException.java b/src/main/java/taco/klkl/domain/comment/exception/CommentUserNotMatchException.java new file mode 100644 index 00000000..2b0e4b27 --- /dev/null +++ b/src/main/java/taco/klkl/domain/comment/exception/CommentUserNotMatchException.java @@ -0,0 +1,10 @@ +package taco.klkl.domain.comment.exception; + +import taco.klkl.global.error.exception.CustomException; +import taco.klkl.global.error.exception.ErrorCode; + +public class CommentUserNotMatchException extends CustomException { + public CommentUserNotMatchException() { + super(ErrorCode.COMMENT_USER_NOT_MATCH); + } +} diff --git a/src/main/java/taco/klkl/domain/comment/service/CommentService.java b/src/main/java/taco/klkl/domain/comment/service/CommentService.java index ddf70315..7a63c4f1 100644 --- a/src/main/java/taco/klkl/domain/comment/service/CommentService.java +++ b/src/main/java/taco/klkl/domain/comment/service/CommentService.java @@ -3,108 +3,28 @@ import java.util.List; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import lombok.RequiredArgsConstructor; -import taco.klkl.domain.comment.dao.CommentRepository; -import taco.klkl.domain.comment.domain.Comment; import taco.klkl.domain.comment.dto.request.CommentCreateUpdateRequest; import taco.klkl.domain.comment.dto.response.CommentResponse; -import taco.klkl.domain.comment.exception.CommentNotFoundException; -import taco.klkl.domain.comment.exception.CommentProductNotMatch; -import taco.klkl.domain.notification.service.NotificationService; -import taco.klkl.domain.product.domain.Product; -import taco.klkl.domain.user.domain.User; -import taco.klkl.global.util.ProductUtil; -import taco.klkl.global.util.UserUtil; @Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class CommentService { +public interface CommentService { - private final CommentRepository commentRepository; + List findCommentsByProductId(final Long productId); - private final NotificationService notificationService; - - private final UserUtil userUtil; - private final ProductUtil productUtil; - - public List findCommentsByProductId(final Long productId) { - validateProductId(productId); - final List comments = commentRepository.findAllByProduct_Id(productId); - return comments.stream() - .map(CommentResponse::from) - .toList(); - } - - @Transactional - public CommentResponse createComment( + CommentResponse createComment( final Long productId, final CommentCreateUpdateRequest commentCreateRequestDto - ) { - final Comment comment = createCommentEntity(productId, commentCreateRequestDto); - commentRepository.save(comment); - notificationService.createNotificationByComment(comment); - return CommentResponse.from(comment); - } + ); - @Transactional - public CommentResponse updateComment( + CommentResponse updateComment( final Long productId, final Long commentId, final CommentCreateUpdateRequest commentUpdateRequestDto - ) { - validateProductId(productId); - final Comment comment = commentRepository.findById(commentId) - .orElseThrow(CommentNotFoundException::new); - validateSameProductId(comment, productId); - updateCommentEntity(comment, commentUpdateRequestDto); + ); - return CommentResponse.from(comment); - } - - @Transactional - public void deleteComment( + void deleteComment( final Long productId, final Long commentId - ) { - validateProductId(productId); - final Comment comment = commentRepository.findById(commentId) - .orElseThrow(CommentNotFoundException::new); - validateSameProductId(comment, productId); - commentRepository.delete(comment); - } - - private Comment createCommentEntity( - final Long productId, - final CommentCreateUpdateRequest commentCreateUpdateRequest - ) { - //TODO: getCurrentUser() 함수로 교채 - final User user = userUtil.getCurrentUser(); - final Product product = productUtil.findProductEntityById(productId); - return Comment.of( - product, - user, - commentCreateUpdateRequest.content() - ); - } - - private void updateCommentEntity( - final Comment comment, - final CommentCreateUpdateRequest commentCreateUpdateRequest - ) { - comment.update(commentCreateUpdateRequest.content()); - } - - private void validateProductId(final Long productId) { - productUtil.validateProductId(productId); - } - - private void validateSameProductId(final Comment comment, final Long productId) { - final Long commentProductId = comment.getProduct().getId(); - if (!commentProductId.equals(productId)) { - throw new CommentProductNotMatch(); - } - } + ); } diff --git a/src/main/java/taco/klkl/domain/comment/service/CommentServiceImpl.java b/src/main/java/taco/klkl/domain/comment/service/CommentServiceImpl.java new file mode 100644 index 00000000..924f1716 --- /dev/null +++ b/src/main/java/taco/klkl/domain/comment/service/CommentServiceImpl.java @@ -0,0 +1,123 @@ +package taco.klkl.domain.comment.service; + +import java.util.List; + +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import taco.klkl.domain.comment.dao.CommentRepository; +import taco.klkl.domain.comment.domain.Comment; +import taco.klkl.domain.comment.dto.request.CommentCreateUpdateRequest; +import taco.klkl.domain.comment.dto.response.CommentResponse; +import taco.klkl.domain.comment.exception.CommentNotFoundException; +import taco.klkl.domain.comment.exception.CommentProductNotMatchException; +import taco.klkl.domain.comment.exception.CommentUserNotMatchException; +import taco.klkl.domain.notification.service.NotificationService; +import taco.klkl.domain.product.domain.Product; +import taco.klkl.domain.user.domain.User; +import taco.klkl.global.util.ProductUtil; +import taco.klkl.global.util.UserUtil; + +@Slf4j +@Primary +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class CommentServiceImpl implements CommentService { + + private final CommentRepository commentRepository; + + private final NotificationService notificationService; + + private final UserUtil userUtil; + private final ProductUtil productUtil; + + public List findCommentsByProductId(final Long productId) { + validateProductId(productId); + final List comments = commentRepository.findByProductIdOrderByCreatedAtDesc(productId); + return comments.stream() + .map(CommentResponse::from) + .toList(); + } + + @Transactional + public CommentResponse createComment( + final Long productId, + final CommentCreateUpdateRequest commentCreateRequestDto + ) { + final Comment comment = createCommentEntity(productId, commentCreateRequestDto); + commentRepository.save(comment); + notificationService.createNotificationByComment(comment); + return CommentResponse.from(comment); + } + + @Transactional + public CommentResponse updateComment( + final Long productId, + final Long commentId, + final CommentCreateUpdateRequest commentUpdateRequestDto + ) { + validateProductId(productId); + final Comment comment = commentRepository.findById(commentId) + .orElseThrow(CommentNotFoundException::new); + validateMyComment(comment); + validateSameProductId(comment, productId); + updateCommentEntity(comment, commentUpdateRequestDto); + + return CommentResponse.from(comment); + } + + @Transactional + public void deleteComment( + final Long productId, + final Long commentId + ) { + validateProductId(productId); + final Comment comment = commentRepository.findById(commentId) + .orElseThrow(CommentNotFoundException::new); + validateMyComment(comment); + validateSameProductId(comment, productId); + commentRepository.delete(comment); + } + + private Comment createCommentEntity( + final Long productId, + final CommentCreateUpdateRequest commentCreateUpdateRequest + ) { + final User user = userUtil.getCurrentUser(); + final Product product = productUtil.findProductEntityById(productId); + return Comment.of( + product, + user, + commentCreateUpdateRequest.content() + ); + } + + private void updateCommentEntity( + final Comment comment, + final CommentCreateUpdateRequest commentCreateUpdateRequest + ) { + comment.update(commentCreateUpdateRequest.content()); + } + + private void validateProductId(final Long productId) { + productUtil.validateProductId(productId); + } + + private void validateMyComment(final Comment comment) { + final User me = userUtil.getCurrentUser(); + if (!comment.getUser().equals(me)) { + throw new CommentUserNotMatchException(); + } + } + + private void validateSameProductId(final Comment comment, final Long productId) { + final Long commentProductId = comment.getProduct().getId(); + if (!commentProductId.equals(productId)) { + throw new CommentProductNotMatchException(); + } + } +} diff --git a/src/main/java/taco/klkl/domain/image/controller/ImageController.java b/src/main/java/taco/klkl/domain/image/controller/ImageController.java index fec40a31..b836c8eb 100644 --- a/src/main/java/taco/klkl/domain/image/controller/ImageController.java +++ b/src/main/java/taco/klkl/domain/image/controller/ImageController.java @@ -18,9 +18,8 @@ import taco.klkl.domain.image.dto.request.MultipleImagesUploadRequest; import taco.klkl.domain.image.dto.request.SingleImageUpdateRequest; import taco.klkl.domain.image.dto.request.SingleImageUploadRequest; -import taco.klkl.domain.image.dto.response.MultipleUploadCompleteResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.image.dto.response.PresignedUrlResponse; -import taco.klkl.domain.image.dto.response.SingleUploadCompleteResponse; import taco.klkl.domain.image.service.ImageService; @Slf4j @@ -61,7 +60,7 @@ public List createProductImageUploadUrls( summary = "유저 이미지 업로드 완료 처리", description = "유저 이미지 업로드를 완료 처리합니다." ) - public SingleUploadCompleteResponse uploadCompleteUserImage( + public ImageResponse uploadCompleteUserImage( @Valid @RequestBody final SingleImageUpdateRequest request ) { return imageService.uploadCompleteUserImage(request); @@ -72,7 +71,7 @@ public SingleUploadCompleteResponse uploadCompleteUserImage( summary = "상품 이미지 업로드 완료 처리", description = "상품 이미지 업로드를 완료 처리합니다." ) - public MultipleUploadCompleteResponse uploadCompleteProductImages( + public List uploadCompleteProductImages( @PathVariable final Long productId, @Valid @RequestBody final MultipleImagesUpdateRequest request ) { diff --git a/src/main/java/taco/klkl/domain/image/dto/response/ImageResponse.java b/src/main/java/taco/klkl/domain/image/dto/response/ImageResponse.java new file mode 100644 index 00000000..9852d5e8 --- /dev/null +++ b/src/main/java/taco/klkl/domain/image/dto/response/ImageResponse.java @@ -0,0 +1,15 @@ +package taco.klkl.domain.image.dto.response; + +import taco.klkl.domain.image.domain.Image; + +public record ImageResponse( + Long id, + String url +) { + public static ImageResponse from(final Image image) { + if (image == null) { + return null; + } + return new ImageResponse(image.getId(), image.getUrl()); + } +} diff --git a/src/main/java/taco/klkl/domain/image/dto/response/MultipleUploadCompleteResponse.java b/src/main/java/taco/klkl/domain/image/dto/response/MultipleUploadCompleteResponse.java deleted file mode 100644 index d7c32c15..00000000 --- a/src/main/java/taco/klkl/domain/image/dto/response/MultipleUploadCompleteResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package taco.klkl.domain.image.dto.response; - -import java.util.List; - -public record MultipleUploadCompleteResponse( - List imageIds -) { - public static MultipleUploadCompleteResponse from(final List imageIds) { - return new MultipleUploadCompleteResponse(imageIds); - } -} diff --git a/src/main/java/taco/klkl/domain/image/dto/response/SingleUploadCompleteResponse.java b/src/main/java/taco/klkl/domain/image/dto/response/SingleUploadCompleteResponse.java deleted file mode 100644 index 58f9178d..00000000 --- a/src/main/java/taco/klkl/domain/image/dto/response/SingleUploadCompleteResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package taco.klkl.domain.image.dto.response; - -public record SingleUploadCompleteResponse( - Long imageId -) { - public static SingleUploadCompleteResponse from(final Long imageId) { - return new SingleUploadCompleteResponse(imageId); - } -} diff --git a/src/main/java/taco/klkl/domain/image/service/ImageService.java b/src/main/java/taco/klkl/domain/image/service/ImageService.java index 6f76f2c6..56292fe0 100644 --- a/src/main/java/taco/klkl/domain/image/service/ImageService.java +++ b/src/main/java/taco/klkl/domain/image/service/ImageService.java @@ -8,9 +8,8 @@ import taco.klkl.domain.image.dto.request.MultipleImagesUploadRequest; import taco.klkl.domain.image.dto.request.SingleImageUpdateRequest; import taco.klkl.domain.image.dto.request.SingleImageUploadRequest; -import taco.klkl.domain.image.dto.response.MultipleUploadCompleteResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.image.dto.response.PresignedUrlResponse; -import taco.klkl.domain.image.dto.response.SingleUploadCompleteResponse; @Service public interface ImageService { @@ -22,11 +21,9 @@ List createProductImageUploadUrls( final MultipleImagesUploadRequest uploadRequest ); - SingleUploadCompleteResponse uploadCompleteUserImage( - final SingleImageUpdateRequest updateRequest - ); + ImageResponse uploadCompleteUserImage(final SingleImageUpdateRequest updateRequest); - MultipleUploadCompleteResponse uploadCompleteProductImages( + List uploadCompleteProductImages( final Long productId, final MultipleImagesUpdateRequest updateRequest ); diff --git a/src/main/java/taco/klkl/domain/image/service/ImageServiceImpl.java b/src/main/java/taco/klkl/domain/image/service/ImageServiceImpl.java index ed319743..7e0ae55e 100644 --- a/src/main/java/taco/klkl/domain/image/service/ImageServiceImpl.java +++ b/src/main/java/taco/klkl/domain/image/service/ImageServiceImpl.java @@ -25,9 +25,8 @@ import taco.klkl.domain.image.dto.request.MultipleImagesUploadRequest; import taco.klkl.domain.image.dto.request.SingleImageUpdateRequest; import taco.klkl.domain.image.dto.request.SingleImageUploadRequest; -import taco.klkl.domain.image.dto.response.MultipleUploadCompleteResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.image.dto.response.PresignedUrlResponse; -import taco.klkl.domain.image.dto.response.SingleUploadCompleteResponse; import taco.klkl.domain.product.domain.Product; import taco.klkl.domain.product.domain.ProductImage; import taco.klkl.domain.user.domain.User; @@ -77,7 +76,7 @@ public List createProductImageUploadUrls( @Override @Transactional - public SingleUploadCompleteResponse uploadCompleteUserImage( + public ImageResponse uploadCompleteUserImage( final SingleImageUpdateRequest updateRequest ) { final User currentUser = userUtil.getCurrentUser(); @@ -88,12 +87,12 @@ public SingleUploadCompleteResponse uploadCompleteUserImage( currentUser.updateImage(updatedImage); - return SingleUploadCompleteResponse.from(currentUser.getImage().getId()); + return ImageResponse.from(currentUser.getImage()); } @Override @Transactional - public MultipleUploadCompleteResponse uploadCompleteProductImages( + public List uploadCompleteProductImages( final Long productId, final MultipleImagesUpdateRequest updateRequest ) { @@ -108,12 +107,10 @@ public MultipleUploadCompleteResponse uploadCompleteProductImages( Product product = productUtil.findProductEntityById(productId); product.updateImages(updatedImages); - final List productImageIds = product.getImages().stream() + return product.getImages().stream() .map(ProductImage::getImage) - .map(Image::getId) + .map(ImageResponse::from) .toList(); - - return MultipleUploadCompleteResponse.from(productImageIds); } private PresignedUrlResponse createImageUploadUrl( diff --git a/src/main/java/taco/klkl/domain/like/controller/LikeController.java b/src/main/java/taco/klkl/domain/like/controller/LikeController.java index fa5dad86..9be08d9d 100644 --- a/src/main/java/taco/klkl/domain/like/controller/LikeController.java +++ b/src/main/java/taco/klkl/domain/like/controller/LikeController.java @@ -2,6 +2,7 @@ import org.springframework.http.HttpStatus; 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.RequestMapping; @@ -24,6 +25,12 @@ public class LikeController { private final LikeService likeService; + @GetMapping + @Operation(summary = "특정 상품의 좋아요 여부 조회", description = "특정 상품의 좋아요 여부를 조회합니다.") + public LikeResponse getLike(@PathVariable final Long productId) { + return likeService.getLike(productId); + } + @PostMapping @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "좋아요 누르기", description = "상품에 좋아요를 누릅니다.") diff --git a/src/main/java/taco/klkl/domain/like/service/LikeService.java b/src/main/java/taco/klkl/domain/like/service/LikeService.java index 409cfb5d..c4e7a468 100644 --- a/src/main/java/taco/klkl/domain/like/service/LikeService.java +++ b/src/main/java/taco/klkl/domain/like/service/LikeService.java @@ -9,6 +9,8 @@ @Service public interface LikeService { + LikeResponse getLike(final Long productId); + /** * 상품에 좋아요를 누르는 경우 * @param productId diff --git a/src/main/java/taco/klkl/domain/like/service/LikeServiceImpl.java b/src/main/java/taco/klkl/domain/like/service/LikeServiceImpl.java index 02801eeb..dfb239cf 100644 --- a/src/main/java/taco/klkl/domain/like/service/LikeServiceImpl.java +++ b/src/main/java/taco/klkl/domain/like/service/LikeServiceImpl.java @@ -30,6 +30,17 @@ public class LikeServiceImpl implements LikeService { private final UserUtil userUtil; private final ProductUtil productUtil; + @Override + @Transactional(readOnly = true) + public LikeResponse getLike(final Long productId) { + final Product product = findProductById(productId); + final User user = findCurrentUser(); + if (likeRepository.existsByProductAndUser(product, user)) { + return LikeResponse.of(true, product.getLikeCount()); + } + return LikeResponse.of(false, product.getLikeCount()); + } + @Override public LikeResponse createLike(final Long productId) { final Product product = findProductById(productId); diff --git a/src/main/java/taco/klkl/domain/notification/domain/Notification.java b/src/main/java/taco/klkl/domain/notification/domain/Notification.java index fff23b3f..986af8f0 100644 --- a/src/main/java/taco/klkl/domain/notification/domain/Notification.java +++ b/src/main/java/taco/klkl/domain/notification/domain/Notification.java @@ -4,6 +4,8 @@ import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; import com.querydsl.core.annotations.QueryInit; @@ -41,6 +43,7 @@ public class Notification { @OneToOne @JoinColumn(name = "comment_id") @QueryInit("product.user") + @OnDelete(action = OnDeleteAction.CASCADE) private Comment comment; private Notification(final Comment comment) { diff --git a/src/main/java/taco/klkl/domain/notification/dto/response/NotificationResponse.java b/src/main/java/taco/klkl/domain/notification/dto/response/NotificationResponse.java index 734c6db1..1f394f6d 100644 --- a/src/main/java/taco/klkl/domain/notification/dto/response/NotificationResponse.java +++ b/src/main/java/taco/klkl/domain/notification/dto/response/NotificationResponse.java @@ -2,16 +2,19 @@ import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; + import taco.klkl.domain.comment.dto.response.CommentNotificationResponse; import taco.klkl.domain.notification.domain.Notification; import taco.klkl.domain.product.dto.response.ProductNotificationResponse; +import taco.klkl.global.common.constants.DefaultConstants; public record NotificationResponse( Long id, boolean isRead, ProductNotificationResponse product, CommentNotificationResponse comment, - LocalDateTime createdAt + @JsonFormat(pattern = DefaultConstants.DEFAULT_DATETIME_FORMAT) LocalDateTime createdAt ) { public static NotificationResponse from(final Notification notification) { return new NotificationResponse( diff --git a/src/main/java/taco/klkl/domain/product/controller/ProductController.java b/src/main/java/taco/klkl/domain/product/controller/ProductController.java index 267d4423..b88c5873 100644 --- a/src/main/java/taco/klkl/domain/product/controller/ProductController.java +++ b/src/main/java/taco/klkl/domain/product/controller/ProductController.java @@ -43,7 +43,7 @@ public class ProductController { @GetMapping @Operation(summary = "상품 목록 조회", description = "상품 목록을 조회합니다.") - public PagedResponse findProductsByFilteringAndSorting( + public PagedResponse getProducts( @PageableDefault(size = ProductConstants.DEFAULT_PAGE_SIZE) final Pageable pageable, @RequestParam(name = "city_id", required = false) final Set cityIds, @RequestParam(name = "subcategory_id", required = false) final Set subcategoryIds, @@ -65,7 +65,7 @@ public PagedResponse findProductsByFilteringAndSorting( @GetMapping("/search") @Operation(summary = "제목으로 상품 목록 조회", description = "제목으로 상품 목록을 조회합니다.") - public PagedResponse findProductsByPartialNameAndSorting( + public PagedResponse searchProductsByName( @RequestParam(value = "name") @NotBlank final String partialName, @PageableDefault(size = ProductConstants.DEFAULT_PAGE_SIZE) final Pageable pageable, @RequestParam(name = "sort_by", required = false, defaultValue = "created_at") final String sortBy, @@ -80,16 +80,16 @@ public PagedResponse findProductsByPartialNameAndSorting( @GetMapping("/following") @Operation(summary = "내 팔로잉의 상품 목록 조회", description = "내 팔로잉 유저들의 상품 목록을 조회합니다.") - public PagedResponse findFollowingProducts( + public PagedResponse getMyFollowingProducts( @PageableDefault(size = ProductConstants.DEFAULT_PAGE_SIZE) final Pageable pageable, - @RequestParam(value = "following_id", required = false) final Set followingIds + @RequestParam(value = "user_id", required = false) final Set userIds ) { - return productService.findMyFollowingProducts(pageable, followingIds); + return productService.findFollowingProducts(pageable, userIds); } @GetMapping("/{productId}") @Operation(summary = "상품 상세 조회", description = "상품 상세 정보를 조회합니다.") - public ProductDetailResponse findProductById( + public ProductDetailResponse getProduct( @PathVariable final Long productId ) { return productService.findProductById(productId); diff --git a/src/main/java/taco/klkl/domain/product/domain/Product.java b/src/main/java/taco/klkl/domain/product/domain/Product.java index 0afc94a7..5d63052b 100644 --- a/src/main/java/taco/klkl/domain/product/domain/Product.java +++ b/src/main/java/taco/klkl/domain/product/domain/Product.java @@ -249,12 +249,11 @@ public void updateImages(final List updateImages) { }); } - public String getMainImageUrl() { + public Image getMainImage() { if (images.isEmpty()) { return null; } - final Image mainImage = images.get(0).getImage(); - return mainImage.getUrl(); + return images.get(0).getImage(); } private Product( diff --git a/src/main/java/taco/klkl/domain/product/dto/response/ProductDetailResponse.java b/src/main/java/taco/klkl/domain/product/dto/response/ProductDetailResponse.java index f49627c7..d83a1944 100644 --- a/src/main/java/taco/klkl/domain/product/dto/response/ProductDetailResponse.java +++ b/src/main/java/taco/klkl/domain/product/dto/response/ProductDetailResponse.java @@ -4,17 +4,22 @@ import java.util.List; import java.util.Set; +import com.fasterxml.jackson.annotation.JsonFormat; + import taco.klkl.domain.category.dto.response.subcategory.SubcategoryResponse; import taco.klkl.domain.category.dto.response.tag.TagResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.product.domain.Product; +import taco.klkl.domain.product.domain.ProductImage; import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.currency.CurrencyResponse; import taco.klkl.domain.user.dto.response.UserDetailResponse; +import taco.klkl.global.common.constants.DefaultConstants; import taco.klkl.global.util.ProductUtil; public record ProductDetailResponse( Long id, - List imageUrls, + List images, String name, String description, String address, @@ -26,12 +31,17 @@ public record ProductDetailResponse( SubcategoryResponse subcategory, CurrencyResponse currency, Set tags, - LocalDateTime createdAt + @JsonFormat(pattern = DefaultConstants.DEFAULT_DATETIME_FORMAT) LocalDateTime createdAt ) { public static ProductDetailResponse from(final Product product) { + final List images = product.getImages().stream() + .map(ProductImage::getImage) + .map(ImageResponse::from) + .toList(); + return new ProductDetailResponse( product.getId(), - ProductUtil.generateImageUrlsByProduct(product), + images, product.getName(), product.getDescription(), product.getAddress(), diff --git a/src/main/java/taco/klkl/domain/product/dto/response/ProductNotificationResponse.java b/src/main/java/taco/klkl/domain/product/dto/response/ProductNotificationResponse.java index 4d0a9f0b..e36eaf19 100644 --- a/src/main/java/taco/klkl/domain/product/dto/response/ProductNotificationResponse.java +++ b/src/main/java/taco/klkl/domain/product/dto/response/ProductNotificationResponse.java @@ -1,16 +1,17 @@ package taco.klkl.domain.product.dto.response; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.product.domain.Product; public record ProductNotificationResponse( Long id, - String mainImageUrl, + ImageResponse image, String name ) { public static ProductNotificationResponse from(final Product product) { return new ProductNotificationResponse( product.getId(), - product.getMainImageUrl(), + ImageResponse.from(product.getMainImage()), product.getName() ); } diff --git a/src/main/java/taco/klkl/domain/product/dto/response/ProductSimpleResponse.java b/src/main/java/taco/klkl/domain/product/dto/response/ProductSimpleResponse.java index 9d8dc5c7..2b2e40f1 100644 --- a/src/main/java/taco/klkl/domain/product/dto/response/ProductSimpleResponse.java +++ b/src/main/java/taco/klkl/domain/product/dto/response/ProductSimpleResponse.java @@ -3,12 +3,13 @@ import java.util.Set; import taco.klkl.domain.category.dto.response.tag.TagResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.product.domain.Product; import taco.klkl.global.util.ProductUtil; public record ProductSimpleResponse( Long id, - String mainImageUrl, + ImageResponse image, String name, Integer likeCount, Double rating, @@ -19,7 +20,7 @@ public record ProductSimpleResponse( public static ProductSimpleResponse from(final Product product) { return new ProductSimpleResponse( product.getId(), - product.getMainImageUrl(), + ImageResponse.from(product.getMainImage()), product.getName(), product.getLikeCount(), product.getRating().getValue(), diff --git a/src/main/java/taco/klkl/domain/product/exception/ProductUserNotMatchException.java b/src/main/java/taco/klkl/domain/product/exception/ProductUserNotMatchException.java new file mode 100644 index 00000000..1b589992 --- /dev/null +++ b/src/main/java/taco/klkl/domain/product/exception/ProductUserNotMatchException.java @@ -0,0 +1,10 @@ +package taco.klkl.domain.product.exception; + +import taco.klkl.global.error.exception.CustomException; +import taco.klkl.global.error.exception.ErrorCode; + +public class ProductUserNotMatchException extends CustomException { + public ProductUserNotMatchException() { + super(ErrorCode.PRODUCT_USER_NOT_MATCH); + } +} diff --git a/src/main/java/taco/klkl/domain/product/service/ProductService.java b/src/main/java/taco/klkl/domain/product/service/ProductService.java index 46f9db10..981d24bf 100644 --- a/src/main/java/taco/klkl/domain/product/service/ProductService.java +++ b/src/main/java/taco/klkl/domain/product/service/ProductService.java @@ -29,7 +29,7 @@ PagedResponse findProductsByPartialName( final ProductSortOptions sortOptions ); - PagedResponse findMyFollowingProducts(final Pageable pageable, final Set followingIds); + PagedResponse findFollowingProducts(final Pageable pageable, final Set userIds); ProductDetailResponse findProductById(final Long id) throws ProductNotFoundException; diff --git a/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java b/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java index 0216d8f0..ca783b7c 100644 --- a/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java +++ b/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java @@ -43,6 +43,7 @@ import taco.klkl.domain.product.dto.response.ProductSimpleResponse; import taco.klkl.domain.product.exception.InvalidCityIdsException; import taco.klkl.domain.product.exception.ProductNotFoundException; +import taco.klkl.domain.product.exception.ProductUserNotMatchException; import taco.klkl.domain.product.exception.SortDirectionNotFoundException; import taco.klkl.domain.region.domain.city.City; import taco.klkl.domain.region.domain.city.QCity; @@ -120,15 +121,15 @@ public PagedResponse findProductsByPartialName( } @Override - public PagedResponse findMyFollowingProducts( + public PagedResponse findFollowingProducts( final Pageable pageable, - final Set followingIds + final Set userIds ) { final User me = userUtil.getCurrentUser(); final Pageable sortedPageable = createPageableSortedByCreatedAtDesc(pageable); final Page followingProducts = productRepository.findProductsOfFollowedUsers( me, - followingIds, + userIds, sortedPageable ); return PagedResponse.of(followingProducts, ProductSimpleResponse::from); @@ -369,7 +370,7 @@ private void validateTagIds(final Set tagIds) { private void validateMyProduct(final Product product) { final User me = userUtil.getCurrentUser(); if (!product.getUser().equals(me)) { - throw new ProductNotFoundException(); + throw new ProductUserNotMatchException(); } } } diff --git a/src/main/java/taco/klkl/domain/region/controller/city/CityController.java b/src/main/java/taco/klkl/domain/region/controller/city/CityController.java new file mode 100644 index 00000000..96fe32eb --- /dev/null +++ b/src/main/java/taco/klkl/domain/region/controller/city/CityController.java @@ -0,0 +1,29 @@ +package taco.klkl.domain.region.controller.city; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +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 lombok.extern.slf4j.Slf4j; +import taco.klkl.domain.region.dto.response.city.CityHierarchyResponse; +import taco.klkl.domain.region.service.city.CityService; + +@Slf4j +@RestController +@RequestMapping("/v1/cities") +@RequiredArgsConstructor +@Tag(name = "5. 지역", description = "지역 관련 API") +public class CityController { + + private final CityService cityService; + + @GetMapping("/{cityId}/hierarchy") + @Operation(summary = "특정 도시의 계층 정보 조회", description = "특정 도시의 계층 정보를 조회합니다.") + public CityHierarchyResponse getCityHierarchy(@PathVariable final Long cityId) { + return cityService.findCityHierarchyById(cityId); + } +} diff --git a/src/main/java/taco/klkl/domain/region/controller/country/CountryController.java b/src/main/java/taco/klkl/domain/region/controller/country/CountryController.java index 608aae16..278c260e 100644 --- a/src/main/java/taco/klkl/domain/region/controller/country/CountryController.java +++ b/src/main/java/taco/klkl/domain/region/controller/country/CountryController.java @@ -1,7 +1,5 @@ package taco.klkl.domain.region.controller.country; -import java.util.List; - import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -11,7 +9,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.service.country.CountryService; @@ -24,21 +21,9 @@ public class CountryController { private final CountryService countryService; - @Operation(summary = "모든 국가 조회", description = "모든 국가를 조회합니다.") - @GetMapping() - public List findAllCountries() { - return countryService.findAllCountries(); - } - - @Operation(summary = "국가 하나 조회", description = "countryId로 특정 국가를 조회합니다.") @GetMapping("/{countryId}") - public CountryResponse findCountryById(@PathVariable final Long countryId) { - return countryService.findCountryById(countryId); - } - - @Operation(summary = "국가에 속한 모든 도시 조회", description = "countryId로 특정 국가에 속한 도시들을 조회합니다.") - @GetMapping("/{countryId}/cities") - public List findCitiesByCountryId(@PathVariable final Long countryId) { - return countryService.findCitiesByCountryId(countryId); + @Operation(summary = "단일 국가 정보 조회", description = "countryId로 특정 국가를 조회합니다.") + public CountryResponse getCountry(@PathVariable final Long countryId) { + return countryService.getCountryById(countryId); } } diff --git a/src/main/java/taco/klkl/domain/region/controller/region/RegionController.java b/src/main/java/taco/klkl/domain/region/controller/region/RegionController.java index 31ebf6e6..6493cb32 100644 --- a/src/main/java/taco/klkl/domain/region/controller/region/RegionController.java +++ b/src/main/java/taco/klkl/domain/region/controller/region/RegionController.java @@ -3,7 +3,6 @@ import java.util.List; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -11,7 +10,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.region.RegionResponse; import taco.klkl.domain.region.service.region.RegionService; @@ -24,21 +22,9 @@ public class RegionController { private final RegionService regionService; - @GetMapping() - @Operation(summary = "전체 지역 목록 조회", description = "전체 지역 목록을 조회합니다.") - public List findAllRegions() { + @GetMapping("/hierarchy") + @Operation(summary = "전체 지역의 계층 정보 조회", description = "전체 지역의 계층 정보를 조회합니다.") + public List getAllRegions() { return regionService.findAllRegions(); } - - @GetMapping("/{regionId}") - @Operation(summary = "단일 지역 조회", description = "regionId로 단일 지역을 조회합니다.") - public RegionResponse findRegionById(@PathVariable final Long regionId) { - return regionService.findRegionById(regionId); - } - - @GetMapping("/{regionId}/countries") - @Operation(summary = "특정 지역의 국가 목록 조회", description = "특정 지역의 국가 목록을 조회합니다.") - public List findCountriesByRegionId(@PathVariable final Long regionId) { - return regionService.findCountriesByRegionId(regionId); - } } diff --git a/src/main/java/taco/klkl/domain/region/domain/city/City.java b/src/main/java/taco/klkl/domain/region/domain/city/City.java index a92ed28d..ce04f2e9 100644 --- a/src/main/java/taco/klkl/domain/region/domain/city/City.java +++ b/src/main/java/taco/klkl/domain/region/domain/city/City.java @@ -8,6 +8,7 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -18,6 +19,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class City { + @Transient private CityType cityType; @Id diff --git a/src/main/java/taco/klkl/domain/region/domain/country/Country.java b/src/main/java/taco/klkl/domain/region/domain/country/Country.java index 380ab61e..b5d782da 100644 --- a/src/main/java/taco/klkl/domain/region/domain/country/Country.java +++ b/src/main/java/taco/klkl/domain/region/domain/country/Country.java @@ -11,6 +11,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -23,6 +24,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Country { + @Transient private CountryType countryType; @Id @@ -55,11 +57,11 @@ public class Country { private String code; @Column( - name = "photo", + name = "wallpaper", length = 500, nullable = false ) - private String photo; + private String wallpaper; @ManyToOne( fetch = FetchType.LAZY, @@ -80,14 +82,14 @@ public class Country { private Country( final CountryType countryType, final Region region, - final String photo, + final String wallpaper, final Currency currency ) { this.countryType = countryType; this.region = region; this.name = countryType.getName(); this.code = countryType.getCode(); - this.photo = photo; + this.wallpaper = wallpaper; this.currency = currency; } diff --git a/src/main/java/taco/klkl/domain/region/domain/currency/Currency.java b/src/main/java/taco/klkl/domain/region/domain/currency/Currency.java index 46b46d67..cbf301b6 100644 --- a/src/main/java/taco/klkl/domain/region/domain/currency/Currency.java +++ b/src/main/java/taco/klkl/domain/region/domain/currency/Currency.java @@ -5,6 +5,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -14,6 +15,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Currency { + @Transient private CurrencyType currencyType; @Id diff --git a/src/main/java/taco/klkl/domain/region/domain/region/Region.java b/src/main/java/taco/klkl/domain/region/domain/region/Region.java index 38646235..4811e051 100644 --- a/src/main/java/taco/klkl/domain/region/domain/region/Region.java +++ b/src/main/java/taco/klkl/domain/region/domain/region/Region.java @@ -9,6 +9,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,6 +20,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Region { + @Transient private RegionType regionType; @Id diff --git a/src/main/java/taco/klkl/domain/region/dto/response/city/CityHierarchyResponse.java b/src/main/java/taco/klkl/domain/region/dto/response/city/CityHierarchyResponse.java new file mode 100644 index 00000000..aa85d196 --- /dev/null +++ b/src/main/java/taco/klkl/domain/region/dto/response/city/CityHierarchyResponse.java @@ -0,0 +1,22 @@ +package taco.klkl.domain.region.dto.response.city; + +import taco.klkl.domain.region.domain.city.City; +import taco.klkl.domain.region.domain.country.Country; +import taco.klkl.domain.region.domain.region.Region; + +public record CityHierarchyResponse( + Long cityId, + Long countryId, + Long regionId +) { + public static CityHierarchyResponse from(final City city) { + final Country country = city.getCountry(); + final Region region = country.getRegion(); + + return new CityHierarchyResponse( + city.getId(), + country.getId(), + region.getId() + ); + } +} diff --git a/src/main/java/taco/klkl/domain/region/dto/response/country/CountryResponse.java b/src/main/java/taco/klkl/domain/region/dto/response/country/CountryResponse.java index bab334ed..20181cf1 100644 --- a/src/main/java/taco/klkl/domain/region/dto/response/country/CountryResponse.java +++ b/src/main/java/taco/klkl/domain/region/dto/response/country/CountryResponse.java @@ -1,29 +1,17 @@ package taco.klkl.domain.region.dto.response.country; -import java.util.List; - -import taco.klkl.domain.region.domain.FlagUrlGenerator; import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.dto.response.city.CityResponse; -import taco.klkl.domain.region.dto.response.currency.CurrencyResponse; -import taco.klkl.global.util.CountryUtil; /** * * @param id * @param name - * @param flagUrl - * @param photo - * @param currency - * @param cities + * @param wallpaper */ public record CountryResponse( Long id, String name, - String flagUrl, - String photo, - CurrencyResponse currency, - List cities + String wallpaper ) { /** * @@ -34,10 +22,7 @@ public static CountryResponse from(final Country country) { return new CountryResponse( country.getId(), country.getName(), - FlagUrlGenerator.generateSvgUrlByCountryCode(country.getCode()), - country.getPhoto(), - CurrencyResponse.from(country.getCurrency()), - CountryUtil.createCitiesByCountry(country) + country.getWallpaper() ); } } diff --git a/src/main/java/taco/klkl/domain/region/dto/response/country/CountrySimpleResponse.java b/src/main/java/taco/klkl/domain/region/dto/response/country/CountrySimpleResponse.java index c7bb0dff..bc5b6a24 100644 --- a/src/main/java/taco/klkl/domain/region/dto/response/country/CountrySimpleResponse.java +++ b/src/main/java/taco/klkl/domain/region/dto/response/country/CountrySimpleResponse.java @@ -1,27 +1,15 @@ package taco.klkl.domain.region.dto.response.country; -import java.util.List; - import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.dto.response.city.CityResponse; -import taco.klkl.global.util.CountryUtil; -/** - * - * @param id - * @param name - * @param cities - */ public record CountrySimpleResponse( Long id, - String name, - List cities + String name ) { public static CountrySimpleResponse from(final Country country) { return new CountrySimpleResponse( country.getId(), - country.getName(), - CountryUtil.createCitiesByCountry(country) + country.getName() ); } } diff --git a/src/main/java/taco/klkl/domain/region/dto/response/country/CountryWithCitiesResponse.java b/src/main/java/taco/klkl/domain/region/dto/response/country/CountryWithCitiesResponse.java new file mode 100644 index 00000000..d1cd8ee6 --- /dev/null +++ b/src/main/java/taco/klkl/domain/region/dto/response/country/CountryWithCitiesResponse.java @@ -0,0 +1,27 @@ +package taco.klkl.domain.region.dto.response.country; + +import java.util.List; + +import taco.klkl.domain.region.domain.country.Country; +import taco.klkl.domain.region.dto.response.city.CityResponse; +import taco.klkl.global.util.CountryUtil; + +/** + * + * @param id + * @param name + * @param cities + */ +public record CountryWithCitiesResponse( + Long id, + String name, + List cities +) { + public static CountryWithCitiesResponse from(final Country country) { + return new CountryWithCitiesResponse( + country.getId(), + country.getName(), + CountryUtil.createCitiesByCountry(country) + ); + } +} diff --git a/src/main/java/taco/klkl/domain/region/dto/response/region/RegionResponse.java b/src/main/java/taco/klkl/domain/region/dto/response/region/RegionResponse.java index 0ebcf273..86ff536d 100644 --- a/src/main/java/taco/klkl/domain/region/dto/response/region/RegionResponse.java +++ b/src/main/java/taco/klkl/domain/region/dto/response/region/RegionResponse.java @@ -3,7 +3,7 @@ import java.util.List; import taco.klkl.domain.region.domain.region.Region; -import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; +import taco.klkl.domain.region.dto.response.country.CountryWithCitiesResponse; import taco.klkl.global.util.RegionUtil; /** @@ -15,7 +15,7 @@ public record RegionResponse( Long id, String name, - List countries + List countries ) { public static RegionResponse from(final Region region) { diff --git a/src/main/java/taco/klkl/domain/region/service/city/CityService.java b/src/main/java/taco/klkl/domain/region/service/city/CityService.java index 0f79c19b..cb78fa7b 100644 --- a/src/main/java/taco/klkl/domain/region/service/city/CityService.java +++ b/src/main/java/taco/klkl/domain/region/service/city/CityService.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service; +import taco.klkl.domain.region.dto.response.city.CityHierarchyResponse; import taco.klkl.domain.region.dto.response.city.CityResponse; @Service @@ -11,4 +12,5 @@ public interface CityService { List findAllCitiesByPartialString(final String partialString); + CityHierarchyResponse findCityHierarchyById(final Long id); } diff --git a/src/main/java/taco/klkl/domain/region/service/city/CityServiceImpl.java b/src/main/java/taco/klkl/domain/region/service/city/CityServiceImpl.java index 4f77bf78..1717ee9b 100644 --- a/src/main/java/taco/klkl/domain/region/service/city/CityServiceImpl.java +++ b/src/main/java/taco/klkl/domain/region/service/city/CityServiceImpl.java @@ -10,7 +10,9 @@ import lombok.extern.slf4j.Slf4j; import taco.klkl.domain.region.dao.city.CityRepository; import taco.klkl.domain.region.domain.city.City; +import taco.klkl.domain.region.dto.response.city.CityHierarchyResponse; import taco.klkl.domain.region.dto.response.city.CityResponse; +import taco.klkl.domain.region.exception.city.CityNotFoundException; @Slf4j @Primary @@ -31,4 +33,11 @@ public List findAllCitiesByPartialString(final String partialStrin .map(CityResponse::from) .toList(); } + + @Override + public CityHierarchyResponse findCityHierarchyById(final Long id) { + final City city = cityRepository.findById(id) + .orElseThrow(CityNotFoundException::new); + return CityHierarchyResponse.from(city); + } } diff --git a/src/main/java/taco/klkl/domain/region/service/country/CountryService.java b/src/main/java/taco/klkl/domain/region/service/country/CountryService.java index 62aec386..2a03720a 100644 --- a/src/main/java/taco/klkl/domain/region/service/country/CountryService.java +++ b/src/main/java/taco/klkl/domain/region/service/country/CountryService.java @@ -4,17 +4,13 @@ import org.springframework.stereotype.Service; -import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; @Service public interface CountryService { - List findAllCountries(); - - CountryResponse findCountryById(final Long countryId); - - List findCitiesByCountryId(final Long countryId); List findAllCountriesByPartialString(final String partialString); + + CountryResponse getCountryById(final Long id); } diff --git a/src/main/java/taco/klkl/domain/region/service/country/CountryServiceImpl.java b/src/main/java/taco/klkl/domain/region/service/country/CountryServiceImpl.java index 52a34cb7..e8ee0cec 100644 --- a/src/main/java/taco/klkl/domain/region/service/country/CountryServiceImpl.java +++ b/src/main/java/taco/klkl/domain/region/service/country/CountryServiceImpl.java @@ -1,6 +1,5 @@ package taco.klkl.domain.region.service.country; -import java.util.Collections; import java.util.List; import org.springframework.context.annotation.Primary; @@ -11,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; import taco.klkl.domain.region.dao.country.CountryRepository; import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; import taco.klkl.domain.region.exception.country.CountryNotFoundException; @@ -25,33 +23,6 @@ public class CountryServiceImpl implements CountryService { private final CountryRepository countryRepository; - @Override - public List findAllCountries() { - final List countries = countryRepository.findAll(); - if (countries.isEmpty()) { - return Collections.emptyList(); - } - return countries.stream() - .map(CountryResponse::from) - .toList(); - } - - @Override - public CountryResponse findCountryById(final Long countryId) throws CountryNotFoundException { - final Country country = countryRepository.findById(countryId) - .orElseThrow(CountryNotFoundException::new); - return CountryResponse.from(country); - } - - @Override - public List findCitiesByCountryId(final Long countryId) throws CountryNotFoundException { - final Country country = countryRepository.findById(countryId) - .orElseThrow(CountryNotFoundException::new); - return country.getCities().stream() - .map(CityResponse::from) - .toList(); - } - @Override public List findAllCountriesByPartialString(final String partialString) { if (partialString == null || partialString.isEmpty()) { @@ -62,4 +33,11 @@ public List findAllCountriesByPartialString(final String .map(CountrySimpleResponse::from) .toList(); } + + @Override + public CountryResponse getCountryById(final Long id) throws CountryNotFoundException { + final Country country = countryRepository.findById(id) + .orElseThrow(CountryNotFoundException::new); + return CountryResponse.from(country); + } } diff --git a/src/main/java/taco/klkl/domain/region/service/region/RegionService.java b/src/main/java/taco/klkl/domain/region/service/region/RegionService.java index 3f0bd61a..552e8463 100644 --- a/src/main/java/taco/klkl/domain/region/service/region/RegionService.java +++ b/src/main/java/taco/klkl/domain/region/service/region/RegionService.java @@ -4,16 +4,11 @@ import org.springframework.stereotype.Service; -import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.region.RegionResponse; @Service public interface RegionService { - List findAllRegions(); - - RegionResponse findRegionById(final Long id); - RegionResponse findRegionByName(final String name); + List findAllRegions(); - List findCountriesByRegionId(final Long id); } diff --git a/src/main/java/taco/klkl/domain/region/service/region/RegionServiceImpl.java b/src/main/java/taco/klkl/domain/region/service/region/RegionServiceImpl.java index bf8570d2..7e55c714 100644 --- a/src/main/java/taco/klkl/domain/region/service/region/RegionServiceImpl.java +++ b/src/main/java/taco/klkl/domain/region/service/region/RegionServiceImpl.java @@ -10,11 +10,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import taco.klkl.domain.region.dao.region.RegionRepository; -import taco.klkl.domain.region.domain.country.Country; import taco.klkl.domain.region.domain.region.Region; -import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.region.RegionResponse; -import taco.klkl.domain.region.exception.region.RegionNotFoundException; @Slf4j @Primary @@ -35,30 +32,4 @@ public List findAllRegions() { .map(RegionResponse::from) .toList(); } - - @Override - public RegionResponse findRegionById(final Long id) throws RegionNotFoundException { - final Region region = regionRepository.findById(id) - .orElseThrow(RegionNotFoundException::new); - return RegionResponse.from(region); - } - - @Override - public RegionResponse findRegionByName(final String name) throws RegionNotFoundException { - final Region region = regionRepository.findFirstByName(name); - if (region == null) { - throw new RegionNotFoundException(); - } - return RegionResponse.from(region); - } - - @Override - public List findCountriesByRegionId(final Long id) { - final Region findRegion = regionRepository.findById(id) - .orElseThrow(RegionNotFoundException::new); - final List countries = findRegion.getCountries(); - return countries.stream() - .map(CountryResponse::from) - .toList(); - } } diff --git a/src/main/java/taco/klkl/domain/search/controller/SearchController.java b/src/main/java/taco/klkl/domain/search/controller/SearchController.java index de824d9c..243e6570 100644 --- a/src/main/java/taco/klkl/domain/search/controller/SearchController.java +++ b/src/main/java/taco/klkl/domain/search/controller/SearchController.java @@ -25,7 +25,7 @@ public class SearchController { @GetMapping() @Operation(summary = "검색 결과 조회", description = "쿼리로 검색 결과를 조회합니다.") public SearchResponse findSearchByQuery( - @RequestParam(value = "q") @NotBlank String query + @RequestParam(value = "q") @NotBlank final String query ) { return searchService.findSearchResult(query); } diff --git a/src/main/java/taco/klkl/domain/user/controller/UserController.java b/src/main/java/taco/klkl/domain/user/controller/UserController.java index d3467204..f365c5bc 100644 --- a/src/main/java/taco/klkl/domain/user/controller/UserController.java +++ b/src/main/java/taco/klkl/domain/user/controller/UserController.java @@ -22,10 +22,9 @@ import lombok.extern.slf4j.Slf4j; import taco.klkl.domain.product.dto.response.ProductSimpleResponse; import taco.klkl.domain.user.domain.User; -import taco.klkl.domain.user.dto.request.UserFollowRequest; import taco.klkl.domain.user.dto.request.UserUpdateRequest; +import taco.klkl.domain.user.dto.response.FollowResponse; import taco.klkl.domain.user.dto.response.UserDetailResponse; -import taco.klkl.domain.user.dto.response.UserFollowResponse; import taco.klkl.domain.user.dto.response.UserSimpleResponse; import taco.klkl.domain.user.service.UserService; import taco.klkl.global.common.constants.ProductConstants; @@ -82,24 +81,29 @@ public PagedResponse getMyLikes( return userService.getUserLikesById(me.getId(), pageable); } - @GetMapping("/following") + @GetMapping("/me/following") @Operation(summary = "내 팔로잉 목록 조회", description = "내 팔로잉 목록을 조회합니다.") - public List getMyFollowing() { - final User me = userUtil.getCurrentUser(); - return userService.getUserFollowingById(me.getId()); + public List getMyFollowings() { + return userService.getFollowings(); + } + + @GetMapping("/me/following/{userId}") + @Operation(summary = "특정 유저의 팔로우 여부 조회", description = "특정 유저를 팔로우했는지 여부를 조회합니다.") + public FollowResponse getFollowingStatus(@PathVariable final Long userId) { + return userService.getFollowingStatus(userId); } - @PostMapping("/following") + @PostMapping("/me/following/{userId}") @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "유저 팔로우", description = "유저를 팔로우합니다.") - public UserFollowResponse followUser(@Valid @RequestBody final UserFollowRequest request) { - return userService.createUserFollow(request); + public FollowResponse followUser(@PathVariable final Long userId) { + return userService.createFollow(userId); } - @DeleteMapping("/following/{userId}") - @Operation(summary = "유저 팔로우 취소", description = "유저 팔로우를 취소합니다.") - public UserFollowResponse cancelUserFollow(@PathVariable final Long userId) { - return userService.removeUserFollow(userId); + @DeleteMapping("/me/following/{userId}") + @Operation(summary = "유저 언팔로우", description = "유저를 언팔로우합니다") + public FollowResponse unfollowUser(@PathVariable final Long userId) { + return userService.removeFollow(userId); } @PutMapping("/me") diff --git a/src/main/java/taco/klkl/domain/user/dto/request/UserFollowRequest.java b/src/main/java/taco/klkl/domain/user/dto/request/UserFollowRequest.java deleted file mode 100644 index 5487726f..00000000 --- a/src/main/java/taco/klkl/domain/user/dto/request/UserFollowRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package taco.klkl.domain.user.dto.request; - -import jakarta.validation.constraints.NotNull; -import taco.klkl.global.common.constants.UserValidationMessages; - -public record UserFollowRequest( - @NotNull(message = UserValidationMessages.USER_ID_NOT_NULL) - Long userId -) { -} diff --git a/src/main/java/taco/klkl/domain/user/dto/response/UserFollowResponse.java b/src/main/java/taco/klkl/domain/user/dto/response/FollowResponse.java similarity index 55% rename from src/main/java/taco/klkl/domain/user/dto/response/UserFollowResponse.java rename to src/main/java/taco/klkl/domain/user/dto/response/FollowResponse.java index 019ad127..faf502d7 100644 --- a/src/main/java/taco/klkl/domain/user/dto/response/UserFollowResponse.java +++ b/src/main/java/taco/klkl/domain/user/dto/response/FollowResponse.java @@ -2,13 +2,13 @@ import taco.klkl.domain.user.domain.User; -public record UserFollowResponse( +public record FollowResponse( boolean isFollowing, Long followerId, Long followingId ) { - public static UserFollowResponse of(final boolean isFollowing, final User follower, final User following) { - return new UserFollowResponse( + public static FollowResponse of(final boolean isFollowing, final User follower, final User following) { + return new FollowResponse( isFollowing, follower.getId(), following.getId() diff --git a/src/main/java/taco/klkl/domain/user/dto/response/UserDetailResponse.java b/src/main/java/taco/klkl/domain/user/dto/response/UserDetailResponse.java index 40ffbd13..1a583586 100644 --- a/src/main/java/taco/klkl/domain/user/dto/response/UserDetailResponse.java +++ b/src/main/java/taco/klkl/domain/user/dto/response/UserDetailResponse.java @@ -1,22 +1,20 @@ package taco.klkl.domain.user.dto.response; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.user.domain.User; -import taco.klkl.global.util.UserUtil; public record UserDetailResponse( Long id, - String profileUrl, + ImageResponse image, String name, - String description, - int totalLikeCount + String description ) { public static UserDetailResponse from(final User user) { return new UserDetailResponse( user.getId(), - UserUtil.generateProfileUrlByUser(user), + ImageResponse.from(user.getImage()), user.getName(), - user.getDescription(), - 0 + user.getDescription() ); } } diff --git a/src/main/java/taco/klkl/domain/user/dto/response/UserSimpleResponse.java b/src/main/java/taco/klkl/domain/user/dto/response/UserSimpleResponse.java index 3ecc2ec6..23926727 100644 --- a/src/main/java/taco/klkl/domain/user/dto/response/UserSimpleResponse.java +++ b/src/main/java/taco/klkl/domain/user/dto/response/UserSimpleResponse.java @@ -1,17 +1,17 @@ package taco.klkl.domain.user.dto.response; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.user.domain.User; -import taco.klkl.global.util.UserUtil; public record UserSimpleResponse( Long id, - String profileUrl, + ImageResponse image, String name ) { public static UserSimpleResponse from(final User user) { return new UserSimpleResponse( user.getId(), - UserUtil.generateProfileUrlByUser(user), + ImageResponse.from(user.getImage()), user.getName() ); } diff --git a/src/main/java/taco/klkl/domain/user/exception/SelfFollowNotAllowedException.java b/src/main/java/taco/klkl/domain/user/exception/SelfFollowNotAllowedException.java new file mode 100644 index 00000000..b301151e --- /dev/null +++ b/src/main/java/taco/klkl/domain/user/exception/SelfFollowNotAllowedException.java @@ -0,0 +1,10 @@ +package taco.klkl.domain.user.exception; + +import taco.klkl.global.error.exception.CustomException; +import taco.klkl.global.error.exception.ErrorCode; + +public class SelfFollowNotAllowedException extends CustomException { + public SelfFollowNotAllowedException() { + super(ErrorCode.SELF_FOLLOW_NOT_ALLOWED); + } +} diff --git a/src/main/java/taco/klkl/domain/user/service/UserService.java b/src/main/java/taco/klkl/domain/user/service/UserService.java index d0398b68..0e0c4fbe 100644 --- a/src/main/java/taco/klkl/domain/user/service/UserService.java +++ b/src/main/java/taco/klkl/domain/user/service/UserService.java @@ -8,10 +8,9 @@ import taco.klkl.domain.product.dto.response.ProductSimpleResponse; import taco.klkl.domain.user.domain.User; import taco.klkl.domain.user.dto.request.UserCreateRequest; -import taco.klkl.domain.user.dto.request.UserFollowRequest; import taco.klkl.domain.user.dto.request.UserUpdateRequest; +import taco.klkl.domain.user.dto.response.FollowResponse; import taco.klkl.domain.user.dto.response.UserDetailResponse; -import taco.klkl.domain.user.dto.response.UserFollowResponse; import taco.klkl.domain.user.dto.response.UserSimpleResponse; import taco.klkl.global.common.response.PagedResponse; @@ -24,13 +23,15 @@ public interface UserService { PagedResponse getUserLikesById(final Long id, final Pageable pageable); - List getUserFollowingById(final Long id); + List getFollowings(); + + FollowResponse getFollowingStatus(final Long followingId); User createUser(final UserCreateRequest createRequest); - UserFollowResponse createUserFollow(final UserFollowRequest followRequest); + FollowResponse createFollow(final Long followingId); - UserFollowResponse removeUserFollow(final Long followerId); + FollowResponse removeFollow(final Long followingId); UserDetailResponse updateUser(final UserUpdateRequest updateRequest); diff --git a/src/main/java/taco/klkl/domain/user/service/UserServiceImpl.java b/src/main/java/taco/klkl/domain/user/service/UserServiceImpl.java index bf007459..0c2894da 100644 --- a/src/main/java/taco/klkl/domain/user/service/UserServiceImpl.java +++ b/src/main/java/taco/klkl/domain/user/service/UserServiceImpl.java @@ -20,11 +20,11 @@ import taco.klkl.domain.user.domain.Follow; import taco.klkl.domain.user.domain.User; import taco.klkl.domain.user.dto.request.UserCreateRequest; -import taco.klkl.domain.user.dto.request.UserFollowRequest; import taco.klkl.domain.user.dto.request.UserUpdateRequest; +import taco.klkl.domain.user.dto.response.FollowResponse; import taco.klkl.domain.user.dto.response.UserDetailResponse; -import taco.klkl.domain.user.dto.response.UserFollowResponse; import taco.klkl.domain.user.dto.response.UserSimpleResponse; +import taco.klkl.domain.user.exception.SelfFollowNotAllowedException; import taco.klkl.domain.user.exception.UserNotFoundException; import taco.klkl.global.common.response.PagedResponse; import taco.klkl.global.util.LikeUtil; @@ -58,8 +58,7 @@ public UserDetailResponse getUserById(final Long id) { @Override public PagedResponse getUserProductsById(final Long id, final Pageable pageable) { - userRepository.findById(id) - .orElseThrow(UserNotFoundException::new); + validateUser(id); final Pageable sortedPageable = createPageableSortedByCreatedAtDesc(pageable); final Page userProducts = productUtil.findProductsByUserId(id, sortedPageable); return PagedResponse.of(userProducts, ProductSimpleResponse::from); @@ -67,8 +66,7 @@ public PagedResponse getUserProductsById(final Long id, f @Override public PagedResponse getUserLikesById(final Long id, final Pageable pageable) { - userRepository.findById(id) - .orElseThrow(UserNotFoundException::new); + validateUser(id); final Pageable sortedPageable = createPageableSortedByCreatedAtDesc(pageable); final Page likes = likeUtil.findLikesByUserId(id, sortedPageable); final Page likedProducts = likes.map(Like::getProduct); @@ -76,15 +74,23 @@ public PagedResponse getUserLikesById(final Long id, fina } @Override - public List getUserFollowingById(final Long id) { - userRepository.findById(id) - .orElseThrow(UserNotFoundException::new); - return followRepository.findByFollowerId(id).stream() + public List getFollowings() { + final User follower = userUtil.getCurrentUser(); + return followRepository.findByFollowerId(follower.getId()).stream() .map(Follow::getFollowing) .map(UserSimpleResponse::from) .toList(); } + @Override + public FollowResponse getFollowingStatus(final Long followingId) { + final User follower = userUtil.getCurrentUser(); + final User following = userRepository.findById(followingId) + .orElseThrow(UserNotFoundException::new); + final boolean isFollowing = followRepository.existsByFollowerAndFollowing(follower, following); + return FollowResponse.of(isFollowing, follower, following); + } + @Override @Transactional public User createUser(final UserCreateRequest createRequest) { @@ -94,28 +100,29 @@ public User createUser(final UserCreateRequest createRequest) { @Override @Transactional - public UserFollowResponse createUserFollow(final UserFollowRequest followRequest) { + public FollowResponse createFollow(final Long followingId) { final User follower = userUtil.getCurrentUser(); - final User following = userRepository.findById(followRequest.userId()) + final User following = userRepository.findById(followingId) .orElseThrow(UserNotFoundException::new); + validateNotMe(follower, following); if (isFollowPresent(follower, following)) { - return UserFollowResponse.of(true, follower, following); + return FollowResponse.of(true, follower, following); } final Follow follow = Follow.of(follower, following); followRepository.save(follow); - return UserFollowResponse.of(true, follower, following); + return FollowResponse.of(true, follower, following); } @Override @Transactional - public UserFollowResponse removeUserFollow(final Long followerId) { + public FollowResponse removeFollow(final Long followingId) { final User follower = userUtil.getCurrentUser(); - final User following = userRepository.findById(followerId) + final User following = userRepository.findById(followingId) .orElseThrow(UserNotFoundException::new); if (isFollowPresent(follower, following)) { followRepository.deleteByFollowerAndFollowing(follower, following); } - return UserFollowResponse.of(false, follower, following); + return FollowResponse.of(false, follower, following); } @Override @@ -157,4 +164,16 @@ private Pageable createPageableSortedByCreatedAtDesc(final Pageable pageable) { private boolean isFollowPresent(final User follower, final User following) { return followRepository.existsByFollowerAndFollowing(follower, following); } + + private void validateUser(final Long id) { + if (!userRepository.existsById(id)) { + throw new UserNotFoundException(); + } + } + + private void validateNotMe(final User follower, final User following) { + if (follower.equals(following)) { + throw new SelfFollowNotAllowedException(); + } + } } diff --git a/src/main/java/taco/klkl/global/common/constants/DefaultConstants.java b/src/main/java/taco/klkl/global/common/constants/DefaultConstants.java index a5bb9d19..22b030d0 100644 --- a/src/main/java/taco/klkl/global/common/constants/DefaultConstants.java +++ b/src/main/java/taco/klkl/global/common/constants/DefaultConstants.java @@ -4,6 +4,7 @@ public final class DefaultConstants { public static final String DEFAULT_STRING = "'N/A'"; public static final String DEFAULT_INT_STRING = "0"; + public static final String DEFAULT_DATETIME_FORMAT = "yy.MM.dd HH:mm"; public static final int DEFAULT_INT_VALUE = 0; diff --git a/src/main/java/taco/klkl/global/common/constants/UserConstants.java b/src/main/java/taco/klkl/global/common/constants/UserConstants.java index 70e768a0..440e8f70 100644 --- a/src/main/java/taco/klkl/global/common/constants/UserConstants.java +++ b/src/main/java/taco/klkl/global/common/constants/UserConstants.java @@ -1,8 +1,6 @@ package taco.klkl.global.common.constants; public final class UserConstants { - - public static final int DEFAULT_TOTAL_LIKE_COUNT = 0; public static final int USERNAME_SUFFIX_MOD = 9973; private UserConstants() { diff --git a/src/main/java/taco/klkl/global/error/exception/ErrorCode.java b/src/main/java/taco/klkl/global/error/exception/ErrorCode.java index 47929263..c35d97ce 100644 --- a/src/main/java/taco/klkl/global/error/exception/ErrorCode.java +++ b/src/main/java/taco/klkl/global/error/exception/ErrorCode.java @@ -20,6 +20,7 @@ public enum ErrorCode { // User USER_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 사용자입니다."), GENDER_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 성별입니다."), + SELF_FOLLOW_NOT_ALLOWED(HttpStatus.BAD_REQUEST, "자기 자신을 팔로우할 수 없습니다."), // Product PRODUCT_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 상품입니다."), @@ -27,6 +28,7 @@ public enum ErrorCode { SORT_CRITERIA_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 정렬 기준입니다."), SORT_DIRECTION_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 정렬 방향입니다."), INVALID_CITY_IDS(HttpStatus.BAD_REQUEST, "선택한 도시들은 동일한 국가에 속하지 않습니다."), + PRODUCT_USER_NOT_MATCH(HttpStatus.BAD_REQUEST, "다른 유저의 상품입니다."), // Like LIKE_COUNT_OVER_MAXIMUM(HttpStatus.BAD_REQUEST, "상품의 좋아요수가 최대값입니다. 2147483647"), @@ -34,6 +36,7 @@ public enum ErrorCode { // Comment COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 댓글입니다."), + COMMENT_USER_NOT_MATCH(HttpStatus.BAD_REQUEST, "다른 유저의 댓글입니다."), COMMENT_PRODUCT_NOT_MATCH(HttpStatus.BAD_REQUEST, "다른 상품에 있는 댓글입니다."), // Region diff --git a/src/main/java/taco/klkl/global/util/ProductUtil.java b/src/main/java/taco/klkl/global/util/ProductUtil.java index e0642cf3..509a10c3 100644 --- a/src/main/java/taco/klkl/global/util/ProductUtil.java +++ b/src/main/java/taco/klkl/global/util/ProductUtil.java @@ -42,13 +42,6 @@ public void validateProductId(final Long id) { } } - public static List generateImageUrlsByProduct(final Product product) { - return product.getImages().stream() - .map(ProductImage::getImage) - .map(Image::getUrl) - .toList(); - } - public static Set generateTagsByProduct(final Product product) { return Optional.ofNullable(product.getProductTags()) .map(productTag -> productTag.stream() diff --git a/src/main/java/taco/klkl/global/util/RegionUtil.java b/src/main/java/taco/klkl/global/util/RegionUtil.java index 527f5838..b26478ab 100644 --- a/src/main/java/taco/klkl/global/util/RegionUtil.java +++ b/src/main/java/taco/klkl/global/util/RegionUtil.java @@ -5,14 +5,14 @@ import java.util.Optional; import taco.klkl.domain.region.domain.region.Region; -import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; +import taco.klkl.domain.region.dto.response.country.CountryWithCitiesResponse; public class RegionUtil { - public static List createCountriesByRegion(final Region region) { + public static List createCountriesByRegion(final Region region) { return Optional.ofNullable(region.getCountries()) .map(regions -> regions.stream() - .map(CountrySimpleResponse::from) + .map(CountryWithCitiesResponse::from) .toList()) .orElse(Collections.emptyList()); } diff --git a/src/main/java/taco/klkl/global/util/UserUtil.java b/src/main/java/taco/klkl/global/util/UserUtil.java index 5f36cae3..4104e809 100644 --- a/src/main/java/taco/klkl/global/util/UserUtil.java +++ b/src/main/java/taco/klkl/global/util/UserUtil.java @@ -2,13 +2,11 @@ import java.time.Instant; import java.util.Objects; -import java.util.Optional; import org.springframework.stereotype.Component; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import taco.klkl.domain.image.domain.Image; import taco.klkl.domain.user.dao.UserRepository; import taco.klkl.domain.user.domain.User; import taco.klkl.domain.user.exception.UserNotFoundException; @@ -41,12 +39,6 @@ public String createUsername(final String name, final Long oauthMemberId) { return createdName; } - public static String generateProfileUrlByUser(final User user) { - return Optional.ofNullable(user.getImage()) - .map(Image::getUrl) - .orElse(null); - } - private User getTestUser() { return userRepository.findById(1L) .orElseThrow(UserNotFoundException::new); diff --git a/src/main/resources/database/data.sql b/src/main/resources/database/data.sql index ad6f222c..33f76c4f 100644 --- a/src/main/resources/database/data.sql +++ b/src/main/resources/database/data.sql @@ -25,7 +25,7 @@ VALUES (438, 'JPY', '엔'), (446, 'MYR', '링깃'), (447, 'USD', '달러'); -INSERT INTO country(country_id, region_id, name, code, photo, currency_id) +INSERT INTO country(country_id, region_id, name, code, wallpaper, currency_id) VALUES (403, 400, '일본', 'JP', 'image/sample', 438), (404, 400, '중국', 'CN', 'image/sample', 439), (405, 400, '대만', 'TW', 'image/sample', 440), diff --git a/src/test/java/taco/klkl/domain/category/controller/TagControllerTest.java b/src/test/java/taco/klkl/domain/category/controller/TagControllerTest.java deleted file mode 100644 index 5bffee0f..00000000 --- a/src/test/java/taco/klkl/domain/category/controller/TagControllerTest.java +++ /dev/null @@ -1,199 +0,0 @@ -package taco.klkl.domain.category.controller; - -import static org.hamcrest.Matchers.*; -import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -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.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; - -import taco.klkl.domain.category.controller.tag.TagController; -import taco.klkl.domain.category.dao.SubcategoryTagRepository; -import taco.klkl.domain.category.domain.SubcategoryTag; -import taco.klkl.domain.category.domain.subcategory.Subcategory; -import taco.klkl.domain.category.domain.subcategory.SubcategoryType; -import taco.klkl.domain.category.domain.tag.Tag; -import taco.klkl.domain.category.domain.tag.TagType; -import taco.klkl.domain.category.dto.response.tag.TagResponse; -import taco.klkl.domain.category.exception.subcategory.SubcategoryNotFoundException; -import taco.klkl.domain.category.service.SubcategoryTagService; -import taco.klkl.domain.category.service.subcategory.SubcategoryService; -import taco.klkl.global.error.exception.ErrorCode; - -@WebMvcTest(TagController.class) -public class TagControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private SubcategoryService subcategoryService; - - @MockBean - private SubcategoryTagService subcategoryTagService; - - @MockBean - private SubcategoryTagRepository subcategoryTagRepository; - - @Test - @DisplayName("존재하는 Subcategory Id 쿼리가 들어왔을 경우, Tag가 잘 나오는지 테스트") - public void testGetTagsByIdsWithValidQuery() throws Exception { - // given - List subcategoryIds = Arrays.asList(1L, 2L); - - Subcategory mockSubcategory1 = mock(Subcategory.class); - Subcategory mockSubcategory2 = mock(Subcategory.class); - Tag mockTag1 = mock(Tag.class); - Tag mockTag2 = mock(Tag.class); - - SubcategoryTag subcategoryTag1 = SubcategoryTag.of(mockSubcategory1, mockTag1); - SubcategoryTag subcategoryTag2 = SubcategoryTag.of(mockSubcategory1, mockTag2); - SubcategoryTag subcategoryTag3 = SubcategoryTag.of(mockSubcategory2, mockTag1); - - List mockSubcategoryList = Arrays.asList(mockSubcategory1, mockSubcategory2); - - when(mockSubcategory1.getId()).thenReturn(1L); - when(mockSubcategory1.getName()).thenReturn(SubcategoryType.INSTANT_FOOD.getName()); - when(mockSubcategory2.getId()).thenReturn(2L); - when(mockSubcategory2.getName()).thenReturn(SubcategoryType.SNACK.getName()); - - when(mockTag1.getId()).thenReturn(1L); - when(mockTag1.getName()).thenReturn(TagType.CONVENIENCE_STORE.getName()); - when(mockTag2.getId()).thenReturn(2L); - when(mockTag2.getName()).thenReturn(TagType.CILANTRO.getName()); - - when(subcategoryTagRepository.findAllBySubcategory(mockSubcategory1)) - .thenReturn(Arrays.asList(subcategoryTag1, subcategoryTag2)); - when(subcategoryTagRepository.findAllBySubcategory(mockSubcategory2)) - .thenReturn(Collections.singletonList(subcategoryTag3)); - - Set expectedResponse = new HashSet<>(Arrays.asList( - TagResponse.from(mockTag1), - TagResponse.from(mockTag2) - )); - - when(subcategoryService.findSubcategoriesBySubcategoryIds(subcategoryIds)).thenReturn(mockSubcategoryList); - when(subcategoryTagService.findTagsBySubcategoryList(mockSubcategoryList)).thenReturn(expectedResponse); - - // when & then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", "1,2") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(2))) - .andExpect(jsonPath("$.data[*].id", containsInAnyOrder(1, 2))) - .andExpect(jsonPath("$.data[*].name", containsInAnyOrder( - TagType.CONVENIENCE_STORE.getName(), - TagType.CILANTRO.getName() - ))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(subcategoryService, times(1)).findSubcategoriesBySubcategoryIds(subcategoryIds); - verify(subcategoryTagService, times(1)).findTagsBySubcategoryList(mockSubcategoryList); - } - - @Test - @DisplayName("존재하는 Subcategory Id 쿼리가 들어왔지만 Tag가 없는 Subcategory일 경우, Tag가 잘 나오는지 테스트") - public void testGetTagsByIdsWithValidQueryButEmptyOne() throws Exception { - // given - List ids = Arrays.asList(1L, 2L); - - Subcategory mockSubcategory1 = mock(Subcategory.class); - Subcategory mockSubcategory2 = mock(Subcategory.class); - Tag mockTag1 = mock(Tag.class); - Tag mockTag2 = mock(Tag.class); - - SubcategoryTag subcategoryTag1 = SubcategoryTag.of(mockSubcategory1, mockTag1); - SubcategoryTag subcategoryTag2 = SubcategoryTag.of(mockSubcategory1, mockTag2); - - List mockSubcategoryList = Arrays.asList(mockSubcategory1, mockSubcategory2); - - when(mockSubcategory1.getId()).thenReturn(1L); - when(mockSubcategory1.getName()).thenReturn(SubcategoryType.INSTANT_FOOD.getName()); - when(mockSubcategory2.getId()).thenReturn(2L); - when(mockSubcategory2.getName()).thenReturn(SubcategoryType.SNACK.getName()); - - when(mockTag1.getId()).thenReturn(1L); - when(mockTag1.getName()).thenReturn(TagType.CONVENIENCE_STORE.getName()); - when(mockTag2.getId()).thenReturn(2L); - when(mockTag2.getName()).thenReturn(TagType.CILANTRO.getName()); - - when(subcategoryTagRepository.findAllBySubcategory(mockSubcategory1)) - .thenReturn(Arrays.asList(subcategoryTag1, subcategoryTag2)); - when(subcategoryTagRepository.findAllBySubcategory(mockSubcategory2)) - .thenReturn(Collections.emptyList()); - - Set expectedResponse = new HashSet<>(Arrays.asList( - TagResponse.from(mockTag1), - TagResponse.from(mockTag2) - )); - - when(subcategoryService.findSubcategoriesBySubcategoryIds(ids)).thenReturn(mockSubcategoryList); - when(subcategoryTagService.findTagsBySubcategoryList(mockSubcategoryList)).thenReturn(expectedResponse); - - // when & then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", "1,2") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(2))) - .andExpect(jsonPath("$.data[*].id", containsInAnyOrder(1, 2))) - .andExpect(jsonPath("$.data[*].name", containsInAnyOrder( - TagType.CONVENIENCE_STORE.getName(), - TagType.CILANTRO.getName() - ))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(subcategoryService, times(1)).findSubcategoriesBySubcategoryIds(ids); - verify(subcategoryTagService, times(1)).findTagsBySubcategoryList(mockSubcategoryList); - } - - @Test - @DisplayName("존재하지 않는 Subcategory Id 쿼리가 들어올 경우, SubcategoryNotFound Error Response를 반환하는지 테스트") - public void testGetTagsByIdsWithValidQueryButNotExist() throws Exception { - //given - when(subcategoryService.findSubcategoriesBySubcategoryIds(anyList())) - .thenThrow(new SubcategoryNotFoundException()); - - //when & then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", "999") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isNotFound()) - .andExpect(jsonPath("$.isSuccess", is(false))) - .andExpect(jsonPath("$.status", is(ErrorCode.SUBCATEGORY_NOT_FOUND.getHttpStatus().value()))) - .andExpect(jsonPath("$.data.message", is(ErrorCode.SUBCATEGORY_NOT_FOUND.getMessage()))); - } - - @Test - @DisplayName("올바르지 않은 쿼리가 들어올 경우, INVALID_QUERY_FORMAT을 반환하는지 테스트") - public void testGetTagsByIdsWithInvalidQueryFormat() throws Exception { - //given - when(subcategoryService.findSubcategoriesBySubcategoryIds(anyList())) - .thenThrow(MethodArgumentTypeMismatchException.class); - - //when & then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", "1,2") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.isSuccess", is(false))) - .andExpect(jsonPath("$.status", is(ErrorCode.QUERY_TYPE_MISMATCH.getHttpStatus().value()))) - .andExpect(jsonPath("$.data.message", is(ErrorCode.QUERY_TYPE_MISMATCH.getMessage()))); - } -} diff --git a/src/test/java/taco/klkl/domain/category/controller/CategoryControllerTest.java b/src/test/java/taco/klkl/domain/category/controller/category/CategoryControllerTest.java similarity index 50% rename from src/test/java/taco/klkl/domain/category/controller/CategoryControllerTest.java rename to src/test/java/taco/klkl/domain/category/controller/category/CategoryControllerTest.java index 2eaf8aaa..494faf11 100644 --- a/src/test/java/taco/klkl/domain/category/controller/CategoryControllerTest.java +++ b/src/test/java/taco/klkl/domain/category/controller/category/CategoryControllerTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.category.controller; +package taco.klkl.domain.category.controller.category; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; @@ -7,7 +7,6 @@ import java.util.Arrays; import java.util.List; -import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -17,17 +16,13 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import taco.klkl.domain.category.controller.category.CategoryController; -import taco.klkl.domain.category.dao.category.CategoryRepository; import taco.klkl.domain.category.domain.category.Category; import taco.klkl.domain.category.domain.category.CategoryType; import taco.klkl.domain.category.domain.subcategory.Subcategory; import taco.klkl.domain.category.domain.subcategory.SubcategoryType; import taco.klkl.domain.category.dto.response.category.CategoryResponse; import taco.klkl.domain.category.dto.response.subcategory.SubcategoryResponse; -import taco.klkl.domain.category.exception.category.CategoryNotFoundException; import taco.klkl.domain.category.service.category.CategoryService; -import taco.klkl.global.error.exception.ErrorCode; @WebMvcTest(CategoryController.class) public class CategoryControllerTest { @@ -46,7 +41,7 @@ public class CategoryControllerTest { @Test @DisplayName("카테고리 컨트롤러 GlobalResponse로 Wrapping되어 나오는지 Test") - public void testFindAllCategories() throws Exception { + public void testGetAllCategories() throws Exception { // given List categoryResponse = Arrays.asList( new CategoryResponse(1L, "Category1", subcategories.stream() @@ -61,7 +56,7 @@ public void testFindAllCategories() throws Exception { when(categoryService.findAllCategories()).thenReturn(categoryResponse); // then - mockMvc.perform(get("/v1/categories") + mockMvc.perform(get("/v1/categories/hierarchy") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess", is(true))) @@ -74,54 +69,4 @@ public void testFindAllCategories() throws Exception { verify(categoryService, times(1)).findAllCategories(); } - - @Test - @DisplayName("valid id가 들어올 경우 Categoy와 Subcategory가 잘 나오는지 Test") - public void testFindSubcategoryWithValidIdById() throws Exception { - // given - Long id = 1L; - Category mockCategory = mock(Category.class); - CategoryRepository mockCategoryRepository = mock(CategoryRepository.class); - when(mockCategory.getId()).thenReturn(id); - when(mockCategory.getName()).thenReturn(CategoryType.FOOD.getName()); - - when(mockCategoryRepository.findById(id)).thenReturn(Optional.of(mockCategory)); - when(mockCategory.getSubcategories()).thenReturn(subcategories); - CategoryResponse response = CategoryResponse.from(mockCategory); - - // when - when(categoryService.findSubCategoriesByCategoryId(id)).thenReturn(response); - - // then - mockMvc.perform(get("/v1/categories/1/subcategories") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data.id", is(1))) - .andExpect(jsonPath("$.data.name", is(CategoryType.FOOD.getName()))) - .andExpect(jsonPath("$.data.subcategories[0].id", is(subcategory1.getId()))) - .andExpect(jsonPath("$.data.subcategories[0].name", is(SubcategoryType.DRESS.getName()))) - .andExpect(jsonPath("$.data.subcategories[1].id", is(subcategory2.getId()))) - .andExpect(jsonPath("$.data.subcategories[1].name", is(SubcategoryType.HAIR_CARE.getName()))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(categoryService, times(1)).findSubCategoriesByCategoryId(id); - } - - @Test - @DisplayName("invalid한 id가 들어올 경우 GlobalException으로 Wrapping되어 나오는지 Test") - public void testFindSubcategoryWithInvalidIdById() throws Exception { - // given - when(categoryService.findSubCategoriesByCategoryId(anyLong())).thenThrow(new CategoryNotFoundException()); - - // when & then - mockMvc.perform(get("/v1/categories/999/subcategories") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isNotFound()) - .andExpect(jsonPath("$.isSuccess", is(false))) - .andExpect(jsonPath("$.status", is(ErrorCode.CATEGORY_NOT_FOUND.getHttpStatus().value()))) - .andExpect(jsonPath("$.data.message", is(ErrorCode.CATEGORY_NOT_FOUND.getMessage()))); - - verify(categoryService, times(1)).findSubCategoriesByCategoryId(anyLong()); - } } diff --git a/src/test/java/taco/klkl/domain/category/integration/TagIntegrationTest.java b/src/test/java/taco/klkl/domain/category/integration/TagIntegrationTest.java deleted file mode 100644 index 7f8fd10d..00000000 --- a/src/test/java/taco/klkl/domain/category/integration/TagIntegrationTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package taco.klkl.domain.category.integration; - -import static org.hamcrest.Matchers.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.transaction.annotation.Transactional; - -import taco.klkl.domain.category.domain.subcategory.Subcategory; -import taco.klkl.domain.category.dto.response.tag.TagResponse; -import taco.klkl.domain.category.service.SubcategoryTagService; -import taco.klkl.domain.category.service.subcategory.SubcategoryService; -import taco.klkl.global.error.exception.ErrorCode; - -@SpringBootTest -@AutoConfigureMockMvc -@Transactional -public class TagIntegrationTest { - @Autowired - private MockMvc mockMvc; - - @Autowired - private SubcategoryService subcategoryService; - - @Autowired - private SubcategoryTagService subcategoryTagService; - - @Test - @DisplayName("존재하는 Subcategory Id 쿼리가 들어왔을 경우, API 테스트") - public void testGetFilterApiWithValidQuery() throws Exception { - //given - List subcategoryIds = Arrays.asList("310", "311", "312"); - String subcategoryIdsParam = String.join(",", subcategoryIds); - - //when - List subcategoryList = subcategoryService.findSubcategoriesBySubcategoryIds( - subcategoryIds.stream() - .map(Long::parseLong) - .toList() - ); - Set response = - subcategoryTagService.findTagsBySubcategoryList(subcategoryList); - - //then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", subcategoryIdsParam) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(response.size()))); - } - - @Test - @DisplayName("존재하는 Subcategory Id 쿼리가 들어왔지만 Filter가 없는 Subcategory일 경우, Api 테스트") - public void testGetFilterApiWithValidQueryButEmptyOne() throws Exception { - //given - List subcategoryIds = Arrays.asList("310", "311", "312", "315"); - String subcategoryIdsParam = String.join(",", subcategoryIds); - - //when - List subcategoryList = subcategoryService.findSubcategoriesBySubcategoryIds( - subcategoryIds.stream() - .map(Long::parseLong) - .toList() - ); - Set response = - subcategoryTagService.findTagsBySubcategoryList(subcategoryList); - - //then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", subcategoryIdsParam) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(response.size()))); - } - - @Test - @DisplayName("존재하는 않는 Subcategory Id 쿼리가 들어올 경우, Api 테스트") - public void testGetFilterApiWithValidQueryButNotExist() throws Exception { - //given - List subcategoryIds = Arrays.asList("310", "311", "312", "400"); - String subcategoryIdsParam = String.join(",", subcategoryIds); - - //then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", subcategoryIdsParam) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isNotFound()) - .andExpect(jsonPath("$.isSuccess", is(false))) - .andExpect(jsonPath("$.status", is(ErrorCode.SUBCATEGORY_NOT_FOUND.getHttpStatus().value()))) - .andExpect(jsonPath("$.data.message", is(ErrorCode.SUBCATEGORY_NOT_FOUND.getMessage()))); - } - - @Test - @DisplayName("올바르지 않은 쿼리가 들어올 경우, Api 테스트") - public void testGetFilterApiWithInvalidQueryFormat() throws Exception { - //given - List subcategoryIds = Arrays.asList("310", "311", "312", "asdf"); - String subcategoryIdsParam = String.join(",", subcategoryIds); - - //then - mockMvc.perform(get("/v1/tags") - .param("subcategory_id", subcategoryIdsParam) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.isSuccess", is(false))) - .andExpect(jsonPath("$.status", is(ErrorCode.QUERY_TYPE_MISMATCH.getHttpStatus().value()))) - .andExpect(jsonPath("$.data.message", is(ErrorCode.QUERY_TYPE_MISMATCH.getMessage()))); - } -} diff --git a/src/test/java/taco/klkl/domain/category/integration/CategoryIntegrationTest.java b/src/test/java/taco/klkl/domain/category/integration/category/CategoryIntegrationTest.java similarity index 53% rename from src/test/java/taco/klkl/domain/category/integration/CategoryIntegrationTest.java rename to src/test/java/taco/klkl/domain/category/integration/category/CategoryIntegrationTest.java index 2748824d..2b2fc463 100644 --- a/src/test/java/taco/klkl/domain/category/integration/CategoryIntegrationTest.java +++ b/src/test/java/taco/klkl/domain/category/integration/category/CategoryIntegrationTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.category.integration; +package taco.klkl.domain.category.integration.category; import static org.hamcrest.Matchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -37,7 +37,7 @@ void testGetAllCategories() throws Exception { List categoryResponse = categoryService.findAllCategories(); //then - mockMvc.perform(get("/v1/categories") + mockMvc.perform(get("/v1/categories/hierarchy") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.data", hasSize(categoryResponse.size()))) @@ -51,42 +51,4 @@ void testGetAllCategories() throws Exception { .andExpect(jsonPath("$.data[3].subcategories", hasSize(categoryResponse.get(3).subcategories().size()))); } - - @Test - @DisplayName("valid한 id값이 들어왔을 때 테스트") - public void testGetCategoriesWithValidId() throws Exception { - //given - CategoryResponse categoryResponse = - categoryService.findSubCategoriesByCategoryId(300L); - - //when, then - mockMvc.perform(get("/v1/categories/300/subcategories") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data.id", is(categoryResponse.id().intValue()))) - .andExpect(jsonPath("$.data.name", is(categoryResponse.name()))) - .andExpect(jsonPath("$.data.subcategories[0].id", - is(categoryResponse.subcategories().get(0).id().intValue()))) - .andExpect(jsonPath("$.data.subcategories[0].name", - is(categoryResponse.subcategories().get(0).name()))) - .andExpect(jsonPath("$.data.subcategories[1].id", - is(categoryResponse.subcategories().get(1).id().intValue()))) - .andExpect(jsonPath("$.data.subcategories[1].name", - is(categoryResponse.subcategories().get(1).name()))); - } - - @Test - @DisplayName("invalid한 id값이 들어왔을 때 테스트") - public void testGetCategoriesWithInvalidId() throws Exception { - //given - - //when, then - mockMvc.perform(get("/v1/categories/999/subcategories") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isNotFound()) - .andExpect(jsonPath("$.isSuccess", is(false))) - .andExpect(jsonPath("$.status", is(ErrorCode.CATEGORY_NOT_FOUND.getHttpStatus().value()))) - .andExpect(jsonPath("$.data.message", is(ErrorCode.CATEGORY_NOT_FOUND.getMessage()))); - } } diff --git a/src/test/java/taco/klkl/domain/category/service/SubcategoryTagServiceImplTest.java b/src/test/java/taco/klkl/domain/category/service/SubcategoryTagServiceImplTest.java deleted file mode 100644 index d765777c..00000000 --- a/src/test/java/taco/klkl/domain/category/service/SubcategoryTagServiceImplTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package taco.klkl.domain.category.service; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import taco.klkl.domain.category.dao.SubcategoryTagRepository; -import taco.klkl.domain.category.domain.SubcategoryTag; -import taco.klkl.domain.category.domain.subcategory.Subcategory; -import taco.klkl.domain.category.domain.tag.Tag; -import taco.klkl.domain.category.domain.tag.TagType; -import taco.klkl.domain.category.dto.response.tag.TagResponse; - -@ExtendWith(MockitoExtension.class) -public class SubcategoryTagServiceImplTest { - - @InjectMocks - private SubcategoryTagServiceImpl subcategoryTagService; - - @Mock - private SubcategoryTagRepository subcategoryTagRepository; - - @Mock - private Subcategory subcategory1; - - @Mock - private Subcategory subcategory2; - - @Mock - private Tag tag1; - - @Mock - private Tag tag2; - - @Mock - private SubcategoryTag subcategoryTag1; - - @Mock - private SubcategoryTag subcategoryTag2; - - @Test - @DisplayName("SubcategoryTagService가 TagResponse 세트를 올바르게 반환하는지 테스트") - public void testFindTagsBySubcategoryList() { - // given - List subcategoryList = Arrays.asList(subcategory1, subcategory2); - - when(subcategoryTagRepository.findAllBySubcategory(subcategory1)) - .thenReturn(Arrays.asList(subcategoryTag1, subcategoryTag2)); - when(subcategoryTagRepository.findAllBySubcategory(subcategory2)) - .thenReturn(Arrays.asList(subcategoryTag1)); - - when(subcategoryTag1.getTag()).thenReturn(tag1); - when(subcategoryTag2.getTag()).thenReturn(tag2); - - when(tag1.getId()).thenReturn(1L); - when(tag1.getName()).thenReturn(TagType.CONVENIENCE_STORE.getName()); - when(tag2.getId()).thenReturn(2L); - when(tag2.getName()).thenReturn(TagType.CILANTRO.getName()); - - // when - Set result = subcategoryTagService.findTagsBySubcategoryList(subcategoryList); - - // then - assertNotNull(result); - assertEquals(2, result.size()); - - assertTrue(result.stream().anyMatch( - tag -> tag.id().equals(1L) && tag.name().equals(TagType.CONVENIENCE_STORE.getName())) - ); - assertTrue(result.stream().anyMatch( - tag -> tag.id().equals(2L) && tag.name().equals(TagType.CILANTRO.getName())) - ); - - verify(subcategoryTagRepository, times(1)).findAllBySubcategory(subcategory1); - verify(subcategoryTagRepository, times(1)).findAllBySubcategory(subcategory2); - } - - @Test - @DisplayName("빈 Subcategory 리스트에 대해 빈 TagResponse 세트를 반환하는지 테스트") - public void testFindTagsByEmptySubcategoryList() { - // given - List emptySubcategoryList = Arrays.asList(); - - // when - Set result = subcategoryTagService.findTagsBySubcategoryList(emptySubcategoryList); - - // then - assertNotNull(result); - assertTrue(result.isEmpty()); - - verify(subcategoryTagRepository, never()).findAllBySubcategory(any()); - } -} diff --git a/src/test/java/taco/klkl/domain/category/service/CategoryServiceImplTest.java b/src/test/java/taco/klkl/domain/category/service/category/CategoryServiceImplTest.java similarity index 64% rename from src/test/java/taco/klkl/domain/category/service/CategoryServiceImplTest.java rename to src/test/java/taco/klkl/domain/category/service/category/CategoryServiceImplTest.java index 99321373..ef17f4e7 100644 --- a/src/test/java/taco/klkl/domain/category/service/CategoryServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/category/service/category/CategoryServiceImplTest.java @@ -1,11 +1,10 @@ -package taco.klkl.domain.category.service; +package taco.klkl.domain.category.service.category; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.List; -import java.util.Optional; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -22,8 +21,6 @@ import taco.klkl.domain.category.domain.subcategory.Subcategory; import taco.klkl.domain.category.domain.subcategory.SubcategoryType; import taco.klkl.domain.category.dto.response.category.CategoryResponse; -import taco.klkl.domain.category.exception.category.CategoryNotFoundException; -import taco.klkl.domain.category.service.category.CategoryServiceImpl; @Transactional @ExtendWith(MockitoExtension.class) @@ -64,44 +61,6 @@ void testFindAllCategories() { verify(categoryRepository, times(1)).findAll(); } - @Test - @DisplayName("Valid한 카테고리ID 입력시 해당하는 서브카테고리를 반환하는지 테스트") - void testFindSubCategoriesByCategoryIdWithValidCategoryId() { - //given - Long categoryId = 1L; - Category mockCategory = mock(Category.class); - - //when - when(mockCategory.getSubcategories()).thenReturn(subcategories); - when(mockCategory.getName()).thenReturn(CategoryType.FOOD.getName()); - when(categoryRepository.findById(categoryId)).thenReturn(Optional.of(mockCategory)); - CategoryResponse response = categoryService.findSubCategoriesByCategoryId(categoryId); - - //then - assertNotNull(response); - assertEquals(SubcategoryType.SNACK.getName(), response.subcategories().get(0).name()); - assertEquals(SubcategoryType.INSTANT_FOOD.getName(), response.subcategories().get(1).name()); - - verify(categoryRepository, times(1)).findById(1L); - } - - @Test - @DisplayName("Invalid한 카테고리 ID 입력시 CategoryNotFoundException을 반환하는지 테스트") - void testFindSubCategoriesByCategoryIdWithInvalidCategoryId() { - //given - Long categoryId = 1L; - - //when - when(categoryRepository.findById(categoryId)).thenThrow(CategoryNotFoundException.class); - - //then - assertThrows(CategoryNotFoundException.class, () -> { - categoryService.findSubCategoriesByCategoryId(categoryId); - }); - - verify(categoryRepository, times(1)).findById(categoryId); - } - @Test @DisplayName("CategoryName리스트로 Category 조회") void testFindAllCategoriesByPartialString() { diff --git a/src/test/java/taco/klkl/domain/category/service/SubcategoryServiceImplTest.java b/src/test/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImplTest.java similarity index 55% rename from src/test/java/taco/klkl/domain/category/service/SubcategoryServiceImplTest.java rename to src/test/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImplTest.java index 44ce200c..ec822f45 100644 --- a/src/test/java/taco/klkl/domain/category/service/SubcategoryServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/category/service/subcategory/SubcategoryServiceImplTest.java @@ -1,6 +1,5 @@ -package taco.klkl.domain.category.service; +package taco.klkl.domain.category.service.subcategory; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.Arrays; @@ -21,8 +20,6 @@ import taco.klkl.domain.category.domain.subcategory.Subcategory; import taco.klkl.domain.category.domain.subcategory.SubcategoryType; import taco.klkl.domain.category.dto.response.subcategory.SubcategoryResponse; -import taco.klkl.domain.category.exception.subcategory.SubcategoryNotFoundException; -import taco.klkl.domain.category.service.subcategory.SubcategoryServiceImpl; @ExtendWith(MockitoExtension.class) @Transactional @@ -40,46 +37,7 @@ public class SubcategoryServiceImplTest { private final Subcategory subcategory3 = Subcategory.of(category, SubcategoryType.DRINKS); @Test - @DisplayName("Query id가 Long type으로 입력되고 subcategory가 존재하는 경우") - public void testFindSubcategoriesBySubcategoryIdsWithExistIds() { - //given - final List subcategoriesIds = Arrays.asList(1L, 2L, 3L); - final List subcategoriesList = Arrays.asList(subcategory1, subcategory2, subcategory3); - - when(subcategoryRepository.findAllById(subcategoriesIds)).thenReturn(subcategoriesList); - - //when - List result = subcategoryService.findSubcategoriesBySubcategoryIds(subcategoriesIds); - - //then - assertNotNull(result); - assertEquals(3, result.size()); - - assertEquals(SubcategoryType.SNACK.getName(), result.get(0).getName()); - assertEquals(SubcategoryType.BEVERAGE.getName(), result.get(1).getName()); - assertEquals(SubcategoryType.DRINKS.getName(), result.get(2).getName()); - - verify(subcategoryRepository, times(1)).findAllById(subcategoriesIds); - } - - @Test - @DisplayName("Query id가 Long type으로 입력되고 subcategory가 존재하지 않는 경우") - public void testFindSubcategoriesBySubcategoryIdsWithNotExistIds() { - //given - final List subcategoriesIds = Arrays.asList(1L, 2L, 3L); - - //when - when(subcategoryRepository.findAllById(subcategoriesIds)).thenThrow(SubcategoryNotFoundException.class); - - //then - assertThrows(SubcategoryNotFoundException.class, () -> { - subcategoryService.findSubcategoriesBySubcategoryIds(subcategoriesIds); - }); - verify(subcategoryRepository, times(1)).findAllById(subcategoriesIds); - } - - @Test - @DisplayName("SubcategoryName리스트로 Subcategory 조회") + @DisplayName("부분 이름으로 Subcategory 조회") void testFindAllSubcategoriesByPartialString() { // given String partialName = "foo"; diff --git a/src/test/java/taco/klkl/domain/comment/controller/CommentControllerTest.java b/src/test/java/taco/klkl/domain/comment/controller/CommentControllerTest.java index 484e8071..7b4fb5b6 100644 --- a/src/test/java/taco/klkl/domain/comment/controller/CommentControllerTest.java +++ b/src/test/java/taco/klkl/domain/comment/controller/CommentControllerTest.java @@ -27,8 +27,8 @@ import taco.klkl.domain.comment.dto.request.CommentCreateUpdateRequest; import taco.klkl.domain.comment.dto.response.CommentResponse; import taco.klkl.domain.comment.exception.CommentNotFoundException; -import taco.klkl.domain.comment.exception.CommentProductNotMatch; -import taco.klkl.domain.comment.service.CommentService; +import taco.klkl.domain.comment.exception.CommentProductNotMatchException; +import taco.klkl.domain.comment.service.CommentServiceImpl; import taco.klkl.domain.product.domain.Product; import taco.klkl.domain.product.domain.Rating; import taco.klkl.domain.product.exception.ProductNotFoundException; @@ -52,7 +52,7 @@ public class CommentControllerTest { private MockMvc mockMvc; @MockBean - private CommentService commentService; + private CommentServiceImpl commentServiceImpl; @MockBean private ProductService productService; @@ -81,7 +81,7 @@ public class CommentControllerTest { private final Country country = Country.of( CountryType.MALAYSIA, region, - "image/malaysia-photo.jpg", + "image/malaysia-wallpaper.jpg", currency ); @@ -121,7 +121,7 @@ public void testGetComment() throws Exception { List responseDtos = Arrays.asList(CommentResponse.from(comment1), CommentResponse.from(comment2)); - when(commentService.findCommentsByProductId(productId)).thenReturn(responseDtos); + when(commentServiceImpl.findCommentsByProductId(productId)).thenReturn(responseDtos); //when & then mockMvc.perform(get("/v1/products/{productId}/comments", productId) @@ -134,7 +134,7 @@ public void testGetComment() throws Exception { .andExpect(jsonPath("$.data[1].id", is(comment2.getId()))) .andExpect(jsonPath("$.data[1].content", is(comment2.getContent()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .findCommentsByProductId(productId); } @@ -144,7 +144,7 @@ public void testCreateComment() throws Exception { //given CommentResponse responseDto = CommentResponse.from(comment1); - when(commentService.createComment(any(Long.class), any(CommentCreateUpdateRequest.class))).thenReturn( + when(commentServiceImpl.createComment(any(Long.class), any(CommentCreateUpdateRequest.class))).thenReturn( responseDto); //when & then @@ -157,7 +157,7 @@ public void testCreateComment() throws Exception { .andExpect(jsonPath("$.data.user.id", is(comment1.getUser().getId()))) .andExpect(jsonPath("$.data.content", is(comment1.getContent()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .createComment(productId, commentCreateRequestDto); } @@ -168,7 +168,7 @@ public void testCreateCommentWhenProductNotFound() throws Exception { Long wrongProductId = 2L; doThrow(new ProductNotFoundException()) - .when(commentService) + .when(commentServiceImpl) .createComment(any(Long.class), any(CommentCreateUpdateRequest.class)); //when & then @@ -187,7 +187,7 @@ public void testUpdateComment() throws Exception { ///given CommentResponse responseDto = CommentResponse.from(comment1); - when(commentService.updateComment( + when(commentServiceImpl.updateComment( any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) @@ -203,7 +203,7 @@ public void testUpdateComment() throws Exception { .andExpect(jsonPath("$.data.user.id", is(comment1.getUser().getId()))) .andExpect(jsonPath("$.data.content", is(comment1.getContent()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .updateComment(productId, commentId, commentUpdateRequestDto); } @@ -213,7 +213,7 @@ public void testUpdateCommentWhenCommentNotFound() throws Exception { ///given Long wrongCommentId = 2L; - when(commentService.updateComment(any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) + when(commentServiceImpl.updateComment(any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) .thenThrow(new CommentNotFoundException()); //when & then @@ -225,7 +225,7 @@ public void testUpdateCommentWhenCommentNotFound() throws Exception { .andExpect(jsonPath("$.status", is(ErrorCode.COMMENT_NOT_FOUND.getHttpStatus().value()))) .andExpect(jsonPath("$.data.message", is(ErrorCode.COMMENT_NOT_FOUND.getMessage()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .updateComment(productId, wrongCommentId, commentUpdateRequestDto); } @@ -235,7 +235,7 @@ public void testUpdateCommentWhenProductNotFound() throws Exception { //given Long wrongProductId = 2L; - when(commentService.updateComment(any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) + when(commentServiceImpl.updateComment(any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) .thenThrow(new ProductNotFoundException()); //when & then @@ -247,7 +247,7 @@ public void testUpdateCommentWhenProductNotFound() throws Exception { .andExpect(jsonPath("$.status", is(ErrorCode.PRODUCT_NOT_FOUND.getHttpStatus().value()))) .andExpect(jsonPath("$.data.message", is(ErrorCode.PRODUCT_NOT_FOUND.getMessage()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .updateComment(wrongProductId, commentId, commentUpdateRequestDto); } @@ -256,8 +256,8 @@ public void testUpdateCommentWhenProductNotFound() throws Exception { public void testUpdateCommentWhenExistProductButNotMatchWithComment() throws Exception { //given - when(commentService.updateComment(any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) - .thenThrow(new CommentProductNotMatch()); + when(commentServiceImpl.updateComment(any(Long.class), any(Long.class), any(CommentCreateUpdateRequest.class))) + .thenThrow(new CommentProductNotMatchException()); //when & then mockMvc.perform(put("/v1/products/{wrongProductId}/comments/{commentId}", productId, commentId) @@ -268,7 +268,7 @@ public void testUpdateCommentWhenExistProductButNotMatchWithComment() throws Exc .andExpect(jsonPath("$.status", is(ErrorCode.COMMENT_PRODUCT_NOT_MATCH.getHttpStatus().value()))) .andExpect(jsonPath("$.data.message", is(ErrorCode.COMMENT_PRODUCT_NOT_MATCH.getMessage()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .updateComment(productId, commentId, commentUpdateRequestDto); } @@ -283,7 +283,7 @@ public void testDeleteComment() throws Exception { .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data", nullValue())); - verify(commentService, times(1)).deleteComment(productId, commentId); + verify(commentServiceImpl, times(1)).deleteComment(productId, commentId); } @Test @@ -292,7 +292,7 @@ public void testDeleteCommentWhenCommentNotFound() throws Exception { //given Long wrongCommentId = 2L; - doThrow(new CommentNotFoundException()).when(commentService).deleteComment(productId, wrongCommentId); + doThrow(new CommentNotFoundException()).when(commentServiceImpl).deleteComment(productId, wrongCommentId); //when & then mockMvc.perform(delete("/v1/products/{productId}/comments/{wrongCommentId}", productId, wrongCommentId) @@ -302,7 +302,7 @@ public void testDeleteCommentWhenCommentNotFound() throws Exception { .andExpect(jsonPath("$.status", is(ErrorCode.COMMENT_NOT_FOUND.getHttpStatus().value()))) .andExpect(jsonPath("$.data.message", is(ErrorCode.COMMENT_NOT_FOUND.getMessage()))); - verify(commentService, times(1)).deleteComment(productId, wrongCommentId); + verify(commentServiceImpl, times(1)).deleteComment(productId, wrongCommentId); } @Test @@ -311,7 +311,7 @@ public void testDeleteCommentWhenProductNotFound() throws Exception { //given Long wrongProductId = 2L; - doThrow(new ProductNotFoundException()).when(commentService).deleteComment(wrongProductId, commentId); + doThrow(new ProductNotFoundException()).when(commentServiceImpl).deleteComment(wrongProductId, commentId); //when & then mockMvc.perform(delete("/v1/products/{wrongProductId}/comments/{commentId}", wrongProductId, commentId) @@ -321,7 +321,7 @@ public void testDeleteCommentWhenProductNotFound() throws Exception { .andExpect(jsonPath("$.status", is(ErrorCode.PRODUCT_NOT_FOUND.getHttpStatus().value()))) .andExpect(jsonPath("$.data.message", is(ErrorCode.PRODUCT_NOT_FOUND.getMessage()))); - verify(commentService, times(1)).deleteComment(wrongProductId, commentId); + verify(commentServiceImpl, times(1)).deleteComment(wrongProductId, commentId); } @Test @@ -329,7 +329,7 @@ public void testDeleteCommentWhenProductNotFound() throws Exception { public void testDeleteCommentWhenExistProductButNotMatchWithComment() throws Exception { //given - doThrow(new CommentProductNotMatch()).when(commentService).deleteComment(productId, commentId); + doThrow(new CommentProductNotMatchException()).when(commentServiceImpl).deleteComment(productId, commentId); //when & then mockMvc.perform(delete("/v1/products/{wrongProductId}/comments/{commentId}", productId, commentId) @@ -340,7 +340,7 @@ public void testDeleteCommentWhenExistProductButNotMatchWithComment() throws Exc .andExpect(jsonPath("$.status", is(ErrorCode.COMMENT_PRODUCT_NOT_MATCH.getHttpStatus().value()))) .andExpect(jsonPath("$.data.message", is(ErrorCode.COMMENT_PRODUCT_NOT_MATCH.getMessage()))); - verify(commentService, times(1)) + verify(commentServiceImpl, times(1)) .deleteComment(productId, commentId); } } diff --git a/src/test/java/taco/klkl/domain/comment/integration/CommentIntegrationTest.java b/src/test/java/taco/klkl/domain/comment/integration/CommentIntegrationTest.java index 9f406b78..a02b751b 100644 --- a/src/test/java/taco/klkl/domain/comment/integration/CommentIntegrationTest.java +++ b/src/test/java/taco/klkl/domain/comment/integration/CommentIntegrationTest.java @@ -19,7 +19,7 @@ import taco.klkl.domain.comment.dto.request.CommentCreateUpdateRequest; import taco.klkl.domain.comment.dto.response.CommentResponse; -import taco.klkl.domain.comment.service.CommentService; +import taco.klkl.domain.comment.service.CommentServiceImpl; import taco.klkl.global.error.exception.ErrorCode; @SpringBootTest @@ -30,7 +30,7 @@ public class CommentIntegrationTest { private MockMvc mockMvc; @Autowired - private CommentService commentService; + private CommentServiceImpl commentServiceImpl; @Autowired private ObjectMapper objectMapper; @@ -50,7 +50,7 @@ public class CommentIntegrationTest { @DisplayName("상품에 있는 모든 댓글 반환 통합 테스트") public void testGetComment() throws Exception { //given - List commentResponses = commentService.findCommentsByProductId(productId); + List commentResponses = commentServiceImpl.findCommentsByProductId(productId); //when & then mockMvc.perform(get("/v1/products/{productId}/comments", productId) diff --git a/src/test/java/taco/klkl/domain/comment/service/CommentServiceImplTest.java b/src/test/java/taco/klkl/domain/comment/service/CommentServiceImplTest.java index 510017ff..6a2b68c5 100644 --- a/src/test/java/taco/klkl/domain/comment/service/CommentServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/comment/service/CommentServiceImplTest.java @@ -20,7 +20,7 @@ import taco.klkl.domain.comment.dto.request.CommentCreateUpdateRequest; import taco.klkl.domain.comment.dto.response.CommentResponse; import taco.klkl.domain.comment.exception.CommentNotFoundException; -import taco.klkl.domain.comment.exception.CommentProductNotMatch; +import taco.klkl.domain.comment.exception.CommentProductNotMatchException; import taco.klkl.domain.notification.service.NotificationService; import taco.klkl.domain.product.domain.Product; import taco.klkl.domain.product.exception.ProductNotFoundException; @@ -45,7 +45,7 @@ public class CommentServiceImplTest { private NotificationService notificationService; @InjectMocks - private CommentService commentService; + private CommentServiceImpl commentServiceImpl; private final UserCreateRequest userRequestDto = new UserCreateRequest( "이상화", @@ -77,10 +77,10 @@ public void testFindCommentsByProductId() { List comments = List.of(comment1, comment2); when(product.getId()).thenReturn(productId); - when(commentRepository.findAllByProduct_Id(productId)).thenReturn(comments); + when(commentRepository.findByProductIdOrderByCreatedAtDesc(productId)).thenReturn(comments); //when - List result = commentService.findCommentsByProductId(productId); + List result = commentServiceImpl.findCommentsByProductId(productId); //then assertThat(result.get(0).id()).isEqualTo(comment1.getId()); @@ -90,7 +90,7 @@ public void testFindCommentsByProductId() { assertThat(result.get(0).createdAt()).isEqualTo(comment1.getCreatedAt()); assertThat(result.get(1).createdAt()).isEqualTo(comment2.getCreatedAt()); - verify(commentRepository, times(1)).findAllByProduct_Id(productId); + verify(commentRepository, times(1)).findByProductIdOrderByCreatedAtDesc(productId); } @Test @@ -104,7 +104,7 @@ public void testCreateComment() { when(commentRepository.save(any(Comment.class))).thenReturn(comment); //when - CommentResponse result = commentService.createComment(productId, commentCreateRequestDto); + CommentResponse result = commentServiceImpl.createComment(productId, commentCreateRequestDto); //then assertThat(result.id()).isEqualTo(comment.getId()); @@ -121,11 +121,12 @@ public void testUpdateComment() { Comment comment = Comment.of(product, user, "이거 진짜에요?"); + when(userUtil.getCurrentUser()).thenReturn(user); when(product.getId()).thenReturn(productId); when(commentRepository.findById(commentId)).thenReturn(Optional.of(comment)); //when - CommentResponse result = commentService.updateComment(productId, commentId, commentUpdateRequestDto); + CommentResponse result = commentServiceImpl.updateComment(productId, commentId, commentUpdateRequestDto); //then assertThat(result.id()).isEqualTo(comment.getId()); @@ -146,7 +147,7 @@ public void testUpdateCommentWhenCommentNotFound() { when(product.getId()).thenReturn(productId); //when & then - assertThrows(CommentNotFoundException.class, () -> commentService.deleteComment(productId, commentId)); + assertThrows(CommentNotFoundException.class, () -> commentServiceImpl.deleteComment(productId, commentId)); verify(commentRepository, never()).save(any(Comment.class)); } @@ -162,7 +163,7 @@ public void testUpdateCommentWhenProductNotFound() { //when & then assertThrows(ProductNotFoundException.class, - () -> commentService.updateComment(productId, commentId, commentUpdateRequestDto)); + () -> commentServiceImpl.updateComment(productId, commentId, commentUpdateRequestDto)); verify(commentRepository, never()).save(any(Comment.class)); } @@ -175,12 +176,13 @@ public void testUpdateCommentWhenExistProductButNotMatchWithComment() { Long commentId = 1L; Comment comment = Comment.of(product, user, "이거 진짜에요?"); + when(userUtil.getCurrentUser()).thenReturn(user); when(product.getId()).thenReturn(wrongProductId); when(commentRepository.findById(commentId)).thenReturn(Optional.of(comment)); //when & then - assertThrows(CommentProductNotMatch.class, - () -> commentService.updateComment(productId, commentId, commentUpdateRequestDto)); + assertThrows(CommentProductNotMatchException.class, + () -> commentServiceImpl.updateComment(productId, commentId, commentUpdateRequestDto)); verify(commentRepository, never()).save(any(Comment.class)); } @@ -193,10 +195,11 @@ public void testDeleteComment() { Comment comment = Comment.of(product, user, "이거 진짜에요?"); + when(userUtil.getCurrentUser()).thenReturn(user); when(product.getId()).thenReturn(productId); when(commentRepository.findById(commentId)).thenReturn(Optional.of(comment)); - commentService.deleteComment(productId, commentId); + commentServiceImpl.deleteComment(productId, commentId); verify(commentRepository).findById(commentId); verify(commentRepository).delete(comment); @@ -214,7 +217,7 @@ public void testDeleteCommentWhenCommentNotFound() { when(commentRepository.findById(commentID)).thenReturn(Optional.empty()); //when & then - assertThrows(CommentNotFoundException.class, () -> commentService.deleteComment(productId, commentID)); + assertThrows(CommentNotFoundException.class, () -> commentServiceImpl.deleteComment(productId, commentID)); verify(commentRepository, never()).delete(any(Comment.class)); } @@ -227,7 +230,7 @@ public void testDeleteCommentWhenProductNotFound() { doThrow(ProductNotFoundException.class).when(productUtil).validateProductId(productId); //when & then - assertThrows(ProductNotFoundException.class, () -> commentService.deleteComment(productId, commentID)); + assertThrows(ProductNotFoundException.class, () -> commentServiceImpl.deleteComment(productId, commentID)); verify(commentRepository, never()).delete(any(Comment.class)); } @@ -240,12 +243,13 @@ public void testDeleteCommentWhenExistProductButNotMatchWithComment() { Long commentId = 1L; Comment comment = Comment.of(product, user, "이거 진짜에요?"); + when(userUtil.getCurrentUser()).thenReturn(user); when(product.getId()).thenReturn(wrongProductId); when(commentRepository.findById(commentId)).thenReturn(Optional.of(comment)); //when & then - assertThrows(CommentProductNotMatch.class, - () -> commentService.deleteComment(productId, commentId)); + assertThrows(CommentProductNotMatchException.class, + () -> commentServiceImpl.deleteComment(productId, commentId)); verify(commentRepository, never()).delete(any(Comment.class)); } } diff --git a/src/test/java/taco/klkl/domain/notification/controller/NotificationControllerTest.java b/src/test/java/taco/klkl/domain/notification/controller/NotificationControllerTest.java index 7f2006ab..42605458 100644 --- a/src/test/java/taco/klkl/domain/notification/controller/NotificationControllerTest.java +++ b/src/test/java/taco/klkl/domain/notification/controller/NotificationControllerTest.java @@ -55,7 +55,7 @@ class NotificationControllerTest { NotificationService notificationService; private final User user = User.of("testUser", "테스트입니다."); - private final Country country = Country.of(CountryType.MALAYSIA, region, "photo", currency); + private final Country country = Country.of(CountryType.MALAYSIA, region, "wallpaper", currency); private final City city = City.of(CityType.BORACAY, country); private final Category category = Category.of(CategoryType.CLOTHES); private final Subcategory subcategory = Subcategory.of(category, SubcategoryType.MAKEUP); diff --git a/src/test/java/taco/klkl/domain/notification/service/NotificationServiceImplTest.java b/src/test/java/taco/klkl/domain/notification/service/NotificationServiceImplTest.java index ec04c9b1..470373d7 100644 --- a/src/test/java/taco/klkl/domain/notification/service/NotificationServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/notification/service/NotificationServiceImplTest.java @@ -87,7 +87,7 @@ public void setUp() { Country country = Country.of( CountryType.JAPAN, region, - "image/thailand-photo.jpg", + "image/thailand-wallpaper.jpg", currency ); City city = City.of( diff --git a/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java b/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java index a0e472d6..7cd9d84e 100644 --- a/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java +++ b/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java @@ -27,6 +27,7 @@ import taco.klkl.domain.category.domain.category.CategoryType; import taco.klkl.domain.category.dto.response.subcategory.SubcategoryResponse; import taco.klkl.domain.category.dto.response.tag.TagResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.product.domain.Rating; import taco.klkl.domain.product.dto.request.ProductCreateUpdateRequest; import taco.klkl.domain.product.dto.request.ProductFilterOptions; @@ -60,18 +61,26 @@ public class ProductControllerTest { void setUp() { UserDetailResponse userDetailResponse = new UserDetailResponse( 1L, - "image/profileUrl.jpg", + new ImageResponse(2L, "url"), "userName", - "userDescription", - 100 + "userDescription" ); CityResponse cityResponse = new CityResponse( 1L, "cityName" ); + TagResponse tagResponse1 = new TagResponse( + 1L, + "tagName1" + ); + TagResponse tagResponse2 = new TagResponse( + 2L, + "tagName2" + ); SubcategoryResponse subcategoryResponse = new SubcategoryResponse( 1L, - "subcategoryName" + "subcategoryName", + List.of(tagResponse1, tagResponse2) ); CurrencyResponse currencyResponse = new CurrencyResponse( 1L, @@ -79,18 +88,10 @@ void setUp() { "통화단위", "image/flagUrl.jpg" ); - TagResponse tagResponse1 = new TagResponse( - 1L, - "tagName1" - ); - TagResponse tagResponse2 = new TagResponse( - 2L, - "tagName2" - ); productSimpleResponse = new ProductSimpleResponse( 1L, - "main-image.jpg", + new ImageResponse(2L, "url"), "productName", 10, Rating.FIVE.getValue(), @@ -100,7 +101,11 @@ void setUp() { ); productDetailResponse = new ProductDetailResponse( 1L, - List.of("image1.jpg", "image2.jpg", "image3.jpg"), + List.of( + new ImageResponse(2L, "url"), + new ImageResponse(3L, "url"), + new ImageResponse(4L, "url") + ), "productName", "Description", "123 Street", @@ -255,7 +260,7 @@ void testFindProductsByPartialNameAndSortOption() throws Exception { @Test @DisplayName("상품 상세 조회 - 성공") - void testFindProductById_ShouldReturnProduct() throws Exception { + void testGetProductById_ShouldReturnProduct() throws Exception { // Given when(productService.findProductById(1L)).thenReturn(productDetailResponse); @@ -271,13 +276,11 @@ void testFindProductById_ShouldReturnProduct() throws Exception { .andExpect(jsonPath("$.data.likeCount", is(productDetailResponse.likeCount()))) .andExpect(jsonPath("$.data.rating", is(productSimpleResponse.rating()))) .andExpect(jsonPath("$.data.user.id", is(productDetailResponse.user().id().intValue()))) - .andExpect(jsonPath("$.data.user.profileUrl", - is(productDetailResponse.user().profileUrl()))) + .andExpect(jsonPath("$.data.user.image.id", + is(productDetailResponse.user().image().id().intValue()))) .andExpect(jsonPath("$.data.user.name", is(productDetailResponse.user().name()))) .andExpect(jsonPath("$.data.user.description", is(productDetailResponse.user().description()))) - .andExpect(jsonPath("$.data.user.totalLikeCount", - is(productDetailResponse.user().totalLikeCount()))) .andExpect(jsonPath("$.data.city.id", is(productDetailResponse.city().id().intValue()))) .andExpect(jsonPath("$.data.city.name", is(productDetailResponse.city().name()))) @@ -315,13 +318,11 @@ void testCreateProduct_ShouldReturnCreatedProduct() throws Exception { .andExpect(jsonPath("$.data.likeCount", is(productDetailResponse.likeCount()))) .andExpect(jsonPath("$.data.rating", is(productSimpleResponse.rating()))) .andExpect(jsonPath("$.data.user.id", is(productDetailResponse.user().id().intValue()))) - .andExpect(jsonPath("$.data.user.profileUrl", - is(productDetailResponse.user().profileUrl()))) + .andExpect(jsonPath("$.data.user.image.id", + is(productDetailResponse.user().image().id().intValue()))) .andExpect(jsonPath("$.data.user.name", is(productDetailResponse.user().name()))) .andExpect(jsonPath("$.data.user.description", is(productDetailResponse.user().description()))) - .andExpect(jsonPath("$.data.user.totalLikeCount", - is(productDetailResponse.user().totalLikeCount()))) .andExpect(jsonPath("$.data.city.id", is(productDetailResponse.city().id().intValue()))) .andExpect(jsonPath("$.data.city.name", is(productDetailResponse.city().name()))) @@ -358,13 +359,11 @@ void testUpdateProduct_ShouldReturnUpdatedProduct() throws Exception { .andExpect(jsonPath("$.data.likeCount", is(productDetailResponse.likeCount()))) .andExpect(jsonPath("$.data.rating", is(productSimpleResponse.rating()))) .andExpect(jsonPath("$.data.user.id", is(productDetailResponse.user().id().intValue()))) - .andExpect(jsonPath("$.data.user.profileUrl", - is(productDetailResponse.user().profileUrl()))) + .andExpect(jsonPath("$.data.user.image.id", + is(productDetailResponse.user().image().id().intValue()))) .andExpect(jsonPath("$.data.user.name", is(productDetailResponse.user().name()))) .andExpect(jsonPath("$.data.user.description", is(productDetailResponse.user().description()))) - .andExpect(jsonPath("$.data.user.totalLikeCount", - is(productDetailResponse.user().totalLikeCount()))) .andExpect(jsonPath("$.data.city.id", is(productDetailResponse.city().id().intValue()))) .andExpect(jsonPath("$.data.city.name", is(productDetailResponse.city().name()))) diff --git a/src/test/java/taco/klkl/domain/product/dto/response/ProductSimpleResponseTest.java b/src/test/java/taco/klkl/domain/product/dto/response/ProductSimpleResponseTest.java index 92085f95..9e304807 100644 --- a/src/test/java/taco/klkl/domain/product/dto/response/ProductSimpleResponseTest.java +++ b/src/test/java/taco/klkl/domain/product/dto/response/ProductSimpleResponseTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -19,6 +18,7 @@ import taco.klkl.domain.category.domain.tag.Tag; import taco.klkl.domain.category.domain.tag.TagType; import taco.klkl.domain.category.dto.response.tag.TagResponse; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.product.domain.Product; import taco.klkl.domain.product.domain.ProductTag; import taco.klkl.domain.product.domain.Rating; @@ -56,7 +56,7 @@ void setUp() { Country country = Country.of( CountryType.JAPAN, region, - "image/thailand-photo.jpg", + "image/thailand-wallpaper.jpg", currency ); city = City.of( @@ -115,7 +115,7 @@ void testConstructor() { // when ProductSimpleResponse dto = new ProductSimpleResponse( product.getId(), - product.getMainImageUrl(), + ImageResponse.from(product.getMainImage()), product.getName(), product.getLikeCount(), product.getRating().getValue(), @@ -126,7 +126,6 @@ void testConstructor() { // then assertThat(dto.id()).isEqualTo(product.getId()); - assertThat(dto.mainImageUrl()).isEqualTo(product.getMainImageUrl()); assertThat(dto.name()).isEqualTo(product.getName()); assertThat(dto.likeCount()).isEqualTo(product.getLikeCount()); assertThat(dto.rating()).isEqualTo(product.getRating().getValue()); diff --git a/src/test/java/taco/klkl/domain/product/service/ProductServiceImplTest.java b/src/test/java/taco/klkl/domain/product/service/ProductServiceImplTest.java index 8dc9ef7d..65b50fdd 100644 --- a/src/test/java/taco/klkl/domain/product/service/ProductServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/product/service/ProductServiceImplTest.java @@ -117,7 +117,7 @@ void setUp() { Country country = Country.of( CountryType.JAPAN, region, - "image/thailand-photo.jpg", + "image/thailand-wallpaper.jpg", currency ); city = City.of( diff --git a/src/test/java/taco/klkl/domain/region/controller/CountryControllerTest.java b/src/test/java/taco/klkl/domain/region/controller/CountryControllerTest.java deleted file mode 100644 index 9bc76631..00000000 --- a/src/test/java/taco/klkl/domain/region/controller/CountryControllerTest.java +++ /dev/null @@ -1,128 +0,0 @@ -package taco.klkl.domain.region.controller; - -import static org.hamcrest.Matchers.*; -import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -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.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; - -import taco.klkl.domain.region.controller.country.CountryController; -import taco.klkl.domain.region.dao.country.CountryRepository; -import taco.klkl.domain.region.domain.city.City; -import taco.klkl.domain.region.domain.city.CityType; -import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.domain.country.CountryType; -import taco.klkl.domain.region.domain.currency.Currency; -import taco.klkl.domain.region.domain.currency.CurrencyType; -import taco.klkl.domain.region.domain.region.Region; -import taco.klkl.domain.region.domain.region.RegionType; -import taco.klkl.domain.region.dto.response.city.CityResponse; -import taco.klkl.domain.region.dto.response.country.CountryResponse; -import taco.klkl.domain.region.service.country.CountryService; - -@WebMvcTest(CountryController.class) -public class CountryControllerTest { - - @Autowired - MockMvc mockMvc; - - @MockBean - CountryService countryService; - - @MockBean - private CountryRepository countryRepository; - - private final Region region = Region.from(RegionType.NORTHEAST_ASIA); - private final Currency currency1 = Currency.of(CurrencyType.JAPANESE_YEN); - private final Country country1 = Country.of( - CountryType.JAPAN, - region, - "photo", - currency1); - private final Country country2 = Country.of( - CountryType.TAIWAN, - region, - "photo", - currency1); - private final City city1 = City.of(CityType.OSAKA, country1); - private final City city2 = City.of(CityType.KYOTO, country1); - private final List cities = Arrays.asList(city1, city2); - - @Test - @DisplayName("모든 국가 조회 테스트") - void testFindAllCountries() throws Exception { - // given - List countryResponses = Arrays.asList( - CountryResponse.from(country1), - CountryResponse.from(country2) - ); - - when(countryService.findAllCountries()).thenReturn(countryResponses); - - // when & then - mockMvc.perform(get("/v1/countries") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(2))) - .andExpect(jsonPath("$.data[0].name", is(country1.getName()))) - .andExpect(jsonPath("$.data[1].name", is(country2.getName()))) - .andExpect(jsonPath("$.data[0].currency.code", is(country1.getCurrency().getCode()))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(countryService, times(1)).findAllCountries(); - } - - @Test - @DisplayName("Id로 국가 조회 테스트") - void testFindCountryById() throws Exception { - // given - CountryResponse countryResponse = CountryResponse.from(country1); - - when(countryService.findCountryById(400L)).thenReturn(countryResponse); - - // when & then - mockMvc.perform(get("/v1/countries/400") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data.name", is(country1.getName()))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(countryService, times(1)).findCountryById(400L); - } - - @Test - @DisplayName("국가와 도시 조회") - void testGetCountryWithCities() throws Exception { - // given - Country mockCountry = mock(Country.class); - when(mockCountry.getName()).thenReturn(CountryType.JAPAN.getName()); - when(countryRepository.findById(400L)).thenReturn(Optional.of(mockCountry)); - when(mockCountry.getCities()).thenReturn(cities); - when(countryService.findCitiesByCountryId(400L)).thenReturn(cities.stream().map(CityResponse::from).toList()); - - // when & then - mockMvc.perform(get("/v1/countries/400/cities") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data[0].name", is(cities.get(0).getName()))) - .andExpect(jsonPath("$.data[1].name", is(cities.get(1).getName()))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(countryService, times(1)).findCitiesByCountryId(400L); - } - -} diff --git a/src/test/java/taco/klkl/domain/region/controller/country/CountryControllerTest.java b/src/test/java/taco/klkl/domain/region/controller/country/CountryControllerTest.java new file mode 100644 index 00000000..aacc4791 --- /dev/null +++ b/src/test/java/taco/klkl/domain/region/controller/country/CountryControllerTest.java @@ -0,0 +1,65 @@ +package taco.klkl.domain.region.controller.country; + +import static org.hamcrest.Matchers.*; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +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.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import taco.klkl.domain.region.dao.country.CountryRepository; +import taco.klkl.domain.region.domain.country.Country; +import taco.klkl.domain.region.domain.country.CountryType; +import taco.klkl.domain.region.domain.currency.Currency; +import taco.klkl.domain.region.domain.currency.CurrencyType; +import taco.klkl.domain.region.domain.region.Region; +import taco.klkl.domain.region.domain.region.RegionType; +import taco.klkl.domain.region.dto.response.country.CountryResponse; +import taco.klkl.domain.region.service.country.CountryService; + +@WebMvcTest(CountryController.class) +public class CountryControllerTest { + + @Autowired + MockMvc mockMvc; + + @MockBean + CountryService countryService; + + @MockBean + private CountryRepository countryRepository; + + private final Region region = Region.from(RegionType.NORTHEAST_ASIA); + private final Currency currency1 = Currency.of(CurrencyType.JAPANESE_YEN); + private final Country country1 = Country.of( + CountryType.JAPAN, + region, + "photo", + currency1); + + @Test + @DisplayName("Id로 국가 조회 테스트") + void testFindCountryById() throws Exception { + // given + CountryResponse countryResponse = CountryResponse.from(country1); + + when(countryService.getCountryById(400L)).thenReturn(countryResponse); + + // when & then + mockMvc.perform(get("/v1/countries/400") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess", is(true))) + .andExpect(jsonPath("$.data.name", is(country1.getName()))) + .andExpect(jsonPath("$.timestamp", notNullValue())); + + verify(countryService, times(1)).getCountryById(400L); + } + +} diff --git a/src/test/java/taco/klkl/domain/region/controller/CurrencyControllerTest.java b/src/test/java/taco/klkl/domain/region/controller/currency/CurrencyControllerTest.java similarity index 95% rename from src/test/java/taco/klkl/domain/region/controller/CurrencyControllerTest.java rename to src/test/java/taco/klkl/domain/region/controller/currency/CurrencyControllerTest.java index c9b116a3..9ccf7298 100644 --- a/src/test/java/taco/klkl/domain/region/controller/CurrencyControllerTest.java +++ b/src/test/java/taco/klkl/domain/region/controller/currency/CurrencyControllerTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.region.controller; +package taco.klkl.domain.region.controller.currency; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; @@ -16,7 +16,6 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import taco.klkl.domain.region.controller.currency.CurrencyController; import taco.klkl.domain.region.dao.currency.CurrencyRepository; import taco.klkl.domain.region.domain.currency.Currency; import taco.klkl.domain.region.domain.currency.CurrencyType; diff --git a/src/test/java/taco/klkl/domain/region/controller/RegionControllerTest.java b/src/test/java/taco/klkl/domain/region/controller/region/RegionControllerTest.java similarity index 59% rename from src/test/java/taco/klkl/domain/region/controller/RegionControllerTest.java rename to src/test/java/taco/klkl/domain/region/controller/region/RegionControllerTest.java index 42a1a0ff..afa2592f 100644 --- a/src/test/java/taco/klkl/domain/region/controller/RegionControllerTest.java +++ b/src/test/java/taco/klkl/domain/region/controller/region/RegionControllerTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.region.controller; +package taco.klkl.domain.region.controller.region; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; @@ -8,7 +8,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -18,15 +17,8 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import taco.klkl.domain.region.controller.region.RegionController; -import taco.klkl.domain.region.dao.region.RegionRepository; -import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.domain.country.CountryType; -import taco.klkl.domain.region.domain.currency.Currency; -import taco.klkl.domain.region.domain.currency.CurrencyType; import taco.klkl.domain.region.domain.region.Region; import taco.klkl.domain.region.domain.region.RegionType; -import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.region.RegionResponse; import taco.klkl.domain.region.service.region.RegionService; import taco.klkl.global.error.exception.ErrorCode; @@ -43,23 +35,10 @@ class RegionControllerTest { private final Region region1 = Region.from(RegionType.NORTHEAST_ASIA); private final Region region2 = Region.from(RegionType.SOUTHEAST_ASIA); private final Region region3 = Region.from(RegionType.ETC); - private final Currency currency1 = Currency.of(CurrencyType.JAPANESE_YEN); - private final Country country1 = Country.of( - CountryType.JAPAN, - region1, - "image/japan", - currency1); - private final Country country2 = Country.of( - CountryType.TAIWAN, - region1, - "image/taiwan", - currency1); - private final List countryList = Arrays.asList(country1, - country2); @Test @DisplayName("모든 지역 조회 성공 테스트") - void testFindAllRegions() throws Exception { + void testGetAllRegions() throws Exception { // given List regionResponses = Arrays.asList( RegionResponse.from(region1), @@ -70,7 +49,7 @@ void testFindAllRegions() throws Exception { when(regionService.findAllRegions()).thenReturn(regionResponses); // when & then - mockMvc.perform(get("/v1/regions") + mockMvc.perform(get("/v1/regions/hierarchy") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess", is(true))) @@ -85,12 +64,12 @@ void testFindAllRegions() throws Exception { @Test @DisplayName("모든 지역 조회 empty 테스트") - void testFindAllRegionsEmpty() throws Exception { + void testGetAllRegionsEmpty() throws Exception { // given when(regionService.findAllRegions()).thenReturn(Collections.emptyList()); // when & then - mockMvc.perform(get("/v1/regions") + mockMvc.perform(get("/v1/regions/hierarchy") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess", is(true))) @@ -107,7 +86,7 @@ void testGetRegionsFail() throws Exception { when(regionService.findAllRegions()).thenThrow(RuntimeException.class); // when & then - mockMvc.perform(get("/v1/regions") + mockMvc.perform(get("/v1/regions/hierarchy") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().is5xxServerError()) .andExpect(jsonPath("$.isSuccess", is(false))) @@ -116,28 +95,4 @@ void testGetRegionsFail() throws Exception { verify(regionService, times(1)).findAllRegions(); } - - @Test - @DisplayName("특정 지역에 속한 국가 목록 조회") - void testGetRegionWithCountry() throws Exception { - // given - Region mockRegion = mock(Region.class); - RegionRepository regionRepository = mock(RegionRepository.class); - when(mockRegion.getName()).thenReturn(RegionType.NORTHEAST_ASIA.getName()); - when(regionRepository.findById(1L)).thenReturn(Optional.of(mockRegion)); - when(mockRegion.getCountries()).thenReturn(countryList); - List responseDto = countryList.stream().map(CountryResponse::from).toList(); - when(regionService.findCountriesByRegionId(1L)).thenReturn(responseDto); - - // when & then - mockMvc.perform(get("/v1/regions/1/countries") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data[0].name", is(countryList.get(0).getName()))) - .andExpect(jsonPath("$.data[1].name", is(countryList.get(1).getName()))) - .andExpect(jsonPath("$.timestamp", notNullValue())); - - verify(regionService, times(1)).findCountriesByRegionId(1L); - } } diff --git a/src/test/java/taco/klkl/domain/region/integration/CountryIntegrationTest.java b/src/test/java/taco/klkl/domain/region/integration/country/CountryIntegrationTest.java similarity index 53% rename from src/test/java/taco/klkl/domain/region/integration/CountryIntegrationTest.java rename to src/test/java/taco/klkl/domain/region/integration/country/CountryIntegrationTest.java index 33462824..04cd029d 100644 --- a/src/test/java/taco/klkl/domain/region/integration/CountryIntegrationTest.java +++ b/src/test/java/taco/klkl/domain/region/integration/country/CountryIntegrationTest.java @@ -1,11 +1,9 @@ -package taco.klkl.domain.region.integration; +package taco.klkl.domain.region.integration.country; import static org.hamcrest.Matchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import java.util.List; - import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,7 +13,6 @@ import org.springframework.test.web.servlet.MockMvc; import jakarta.transaction.Transactional; -import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.service.country.CountryService; @@ -30,25 +27,11 @@ public class CountryIntegrationTest { @Autowired CountryService countryService; - @Test - @DisplayName("모든 국가 조회 테스트") - void testGetAllCountries() throws Exception { - // given - List countryResponses = countryService.findAllCountries(); - - // when & then - mockMvc.perform(get("/v1/countries") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(countryResponses.size()))); - } - @Test @DisplayName("id로 국가 조회 테스트") void testGetCountryById() throws Exception { // given - CountryResponse countryResponse = countryService.findCountryById(403L); + CountryResponse countryResponse = countryService.getCountryById(403L); // when & then mockMvc.perform(get("/v1/countries/403") @@ -57,18 +40,4 @@ void testGetCountryById() throws Exception { .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data.name", is(countryResponse.name()))); } - - @Test - @DisplayName("국가에 속한 모든 도시목록 조회") - void testGetCountryWithCitiesById() throws Exception { - // given - List responseDto = countryService.findCitiesByCountryId(403L); - - // when & then - mockMvc.perform(get("/v1/countries/403/cities") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(responseDto.size()))); - } } diff --git a/src/test/java/taco/klkl/domain/region/integration/RegionIntegrationTest.java b/src/test/java/taco/klkl/domain/region/integration/region/RegionIntegrationTest.java similarity index 67% rename from src/test/java/taco/klkl/domain/region/integration/RegionIntegrationTest.java rename to src/test/java/taco/klkl/domain/region/integration/region/RegionIntegrationTest.java index b099ccdf..3b676961 100644 --- a/src/test/java/taco/klkl/domain/region/integration/RegionIntegrationTest.java +++ b/src/test/java/taco/klkl/domain/region/integration/region/RegionIntegrationTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.region.integration; +package taco.klkl.domain.region.integration.region; import static org.hamcrest.Matchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -15,7 +15,6 @@ import org.springframework.test.web.servlet.MockMvc; import jakarta.transaction.Transactional; -import taco.klkl.domain.region.dto.response.country.CountryResponse; import taco.klkl.domain.region.dto.response.region.RegionResponse; import taco.klkl.domain.region.service.region.RegionService; @@ -37,26 +36,10 @@ void testGetAllRegions() throws Exception { List regionResponses = regionService.findAllRegions(); // when & then - mockMvc.perform(get("/v1/regions") + mockMvc.perform(get("/v1/regions/hierarchy") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data", hasSize(regionResponses.size()))); } - - @Test - @DisplayName("지역에 속한 국가목록 조회 테스트") - void testGetCountriesByRegionId() throws Exception { - // given - List countryResponses = regionService.findCountriesByRegionId(400L); - - // when - mockMvc.perform(get("/v1/regions/400/countries") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("isSuccess", is(true))) - .andExpect(jsonPath("$.data", hasSize(countryResponses.size()))); - - // then - } } diff --git a/src/test/java/taco/klkl/domain/region/service/CountryServiceImplTest.java b/src/test/java/taco/klkl/domain/region/service/CountryServiceImplTest.java deleted file mode 100644 index 8b965dea..00000000 --- a/src/test/java/taco/klkl/domain/region/service/CountryServiceImplTest.java +++ /dev/null @@ -1,137 +0,0 @@ -package taco.klkl.domain.region.service; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import taco.klkl.domain.region.dao.country.CountryRepository; -import taco.klkl.domain.region.domain.city.City; -import taco.klkl.domain.region.domain.city.CityType; -import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.domain.country.CountryType; -import taco.klkl.domain.region.domain.currency.Currency; -import taco.klkl.domain.region.domain.currency.CurrencyType; -import taco.klkl.domain.region.domain.region.Region; -import taco.klkl.domain.region.domain.region.RegionType; -import taco.klkl.domain.region.dto.response.city.CityResponse; -import taco.klkl.domain.region.dto.response.country.CountryResponse; -import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; -import taco.klkl.domain.region.exception.country.CountryNotFoundException; -import taco.klkl.domain.region.service.country.CountryServiceImpl; - -@ExtendWith(MockitoExtension.class) -public class CountryServiceImplTest { - - private static final Logger log = LoggerFactory.getLogger(CountryServiceImplTest.class); - @InjectMocks - CountryServiceImpl countryService; - - @Mock - CountryRepository countryRepository; - - private final Region region = Region.from(RegionType.NORTHEAST_ASIA); - private final Currency currency1 = Currency.of(CurrencyType.JAPANESE_YEN); - private final Country country1 = Country.of( - CountryType.JAPAN, - region, - "photo", - currency1); - private final Country country2 = Country.of( - CountryType.TAIWAN, - region, - "photo", - currency1); - private final City city1 = City.of(CityType.OSAKA, country1); - private final City city2 = City.of(CityType.KYOTO, country1); - private final List cities = Arrays.asList(city1, city2); - - @Test - @DisplayName("모든 국가 조회 테스트") - void testFindAllCountries() { - // given - List countries = Arrays.asList(country1, country2); - when(countryRepository.findAll()).thenReturn(countries); - - // when - List findCountries = countryService.findAllCountries(); - - // then - assertThat(findCountries.size()).isEqualTo(countries.size()); - assertThat(findCountries.get(0).name()).isEqualTo(countries.get(0).getName()); - assertThat(findCountries.get(1).name()).isEqualTo(countries.get(1).getName()); - } - - @Test - @DisplayName("id로 국가조회 테스트") - void testFindCountryById() { - // given - when(countryRepository.findById(400L)).thenReturn(Optional.of(country1)); - - // when - CountryResponse findCountry = countryService.findCountryById(400L); - - // then - assertThat(findCountry).isEqualTo(CountryResponse.from(country1)); - } - - @Test - @DisplayName("국가 조회 실패 테스트") - void testFindCountryByIdFail() { - // given - when(countryRepository.findById(400L)).thenThrow(CountryNotFoundException.class); - - // when & then - Assertions.assertThrows(CountryNotFoundException.class, () -> - countryService.findCountryById(400L)); - - verify(countryRepository, times(1)).findById(400L); - } - - @Test - @DisplayName("국가와 도시 조회") - void testGetCountryWithCitiesById() { - // given - Country mockCountry = mock(Country.class); - when(countryRepository.findById(400L)).thenReturn(Optional.of(mockCountry)); - when(mockCountry.getCities()).thenReturn(cities); - - // when - List findCountries = countryService.findCitiesByCountryId(400L); - - // then - assertThat(findCountries.size()).isEqualTo(cities.size()); - assertThat(findCountries.get(0).name()).isEqualTo(cities.get(0).getName()); - assertThat(findCountries.get(1).name()).isEqualTo(cities.get(1).getName()); - } - - @Test - @DisplayName("부분 문자열로 국가 조회") - void testGetCountriesByCountryTypes() { - // given - String partialName = "foo"; - CountrySimpleResponse country1ResponseDto = CountrySimpleResponse.from(country1); - CountrySimpleResponse country2ResponseDto = CountrySimpleResponse.from(country2); - when(countryRepository.findAllByNameContaining(partialName)).thenReturn(Arrays.asList(country1, country2)); - - // when - List countrySimpleResponses = countryService.findAllCountriesByPartialString( - partialName); - - // then - assertThat(countrySimpleResponses).hasSize(2); - assertThat(countrySimpleResponses).containsExactlyInAnyOrder(country1ResponseDto, country2ResponseDto); - } -} diff --git a/src/test/java/taco/klkl/domain/region/service/RegionServiceImplTest.java b/src/test/java/taco/klkl/domain/region/service/RegionServiceImplTest.java deleted file mode 100644 index 461768f8..00000000 --- a/src/test/java/taco/klkl/domain/region/service/RegionServiceImplTest.java +++ /dev/null @@ -1,164 +0,0 @@ -package taco.klkl.domain.region.service; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import taco.klkl.domain.region.dao.region.RegionRepository; -import taco.klkl.domain.region.domain.country.Country; -import taco.klkl.domain.region.domain.country.CountryType; -import taco.klkl.domain.region.domain.currency.Currency; -import taco.klkl.domain.region.domain.currency.CurrencyType; -import taco.klkl.domain.region.domain.region.Region; -import taco.klkl.domain.region.domain.region.RegionType; -import taco.klkl.domain.region.dto.response.country.CountryResponse; -import taco.klkl.domain.region.dto.response.region.RegionResponse; -import taco.klkl.domain.region.exception.region.RegionNotFoundException; -import taco.klkl.domain.region.service.region.RegionServiceImpl; - -@ExtendWith(MockitoExtension.class) -class RegionServiceImplTest { - - @InjectMocks - RegionServiceImpl regionService; - - @Mock - RegionRepository regionRepository; - - private final Region region1 = Region.from(RegionType.NORTHEAST_ASIA); - private final Region region2 = Region.from(RegionType.SOUTHEAST_ASIA); - private final Region region3 = Region.from(RegionType.ETC); - private final Currency currency1 = Currency.of(CurrencyType.JAPANESE_YEN); - private final Country country1 = Country.of( - CountryType.JAPAN, - region1, - "image/japan", - currency1); - private final Country country2 = Country.of( - CountryType.TAIWAN, - region1, - "image/taiwan", - currency1); - private final List countryList = Arrays.asList(country1, - country2); - - @Test - @DisplayName("모든 지역 조회 성공 테스트") - void testGetAllRegion() { - // given - List mockRegions = Arrays.asList(region1, region2, region3); - - when(regionRepository.findAllByOrderByIdAsc()).thenReturn(mockRegions); - - // when - List regionResponses = regionService.findAllRegions(); - - // then - assertThat(regionResponses.size()).isEqualTo(3); - assertThat(regionResponses.get(0).name()).isEqualTo(region1.getName()); - assertThat(regionResponses.get(1).name()).isEqualTo(region2.getName()); - assertThat(regionResponses.get(2).name()).isEqualTo(region3.getName()); - } - - @Test - @DisplayName("모든 지역 조회 실패 테스트") - void testGetAllRegionFail() { - // given - when(regionRepository.findAllByOrderByIdAsc()).thenReturn(Collections.emptyList()); - - // when - List regionResponses = regionService.findAllRegions(); - - // then - assertThat(regionResponses.size()).isEqualTo(0); - } - - @Test - @DisplayName("Id 지역 조회 성공 테스트") - void testFindRegionById() { - // given - when(regionRepository.findById(1L)).thenReturn(Optional.of(region1)); - when(regionRepository.findById(2L)).thenReturn(Optional.of(region2)); - - // when - RegionResponse region1ResponseDto = regionService.findRegionById(1L); - RegionResponse region2ResponseDto = regionService.findRegionById(2L); - - // then - assertThat(region1ResponseDto.name()).isEqualTo(region1.getName()); - assertThat(region2ResponseDto.name()).isEqualTo(region2.getName()); - } - - @Test - @DisplayName("지역에 있는 국가목록 조회") - void testGetRegionWithCountry() { - // given - Region mockRegion = mock(Region.class); - when(regionRepository.findById(1L)).thenReturn(Optional.of(mockRegion)); - when(mockRegion.getCountries()).thenReturn(countryList); - - // when - List countriesDto = regionService.findCountriesByRegionId(1L); - - // then - assertThat(countriesDto.size()).isEqualTo(2); - assertThat(countriesDto.get(0)).isEqualTo(CountryResponse.from(country1)); - assertThat(countriesDto.get(1)).isEqualTo(CountryResponse.from(country2)); - } - - @Test - @DisplayName("Id 지역 조회 실패 테스트") - void testFindRegionByIdFail() { - // given - when(regionRepository.findById(1L)).thenThrow(new RegionNotFoundException()); - - // when & then - Assertions.assertThrows(RegionNotFoundException.class, () -> { - regionService.findRegionById(1L); - }); - - verify(regionRepository, times(1)).findById(1L); - } - - @Test - @DisplayName("Name 지역 조회 성공 테스트") - void testFindRegionByName() { - // given - when(regionRepository.findFirstByName(region1.getName())).thenReturn(region1); - when(regionRepository.findFirstByName(region2.getName())).thenReturn(region2); - - // when - RegionResponse region1ResponseDto = regionService.findRegionByName(region1.getName()); - RegionResponse region2ResponseDto = regionService.findRegionByName(region2.getName()); - - // then - assertThat(region1ResponseDto.name()).isEqualTo(region1.getName()); - assertThat(region2ResponseDto.name()).isEqualTo(region2.getName()); - } - - @Test - @DisplayName("Name 지역 조회 실패 테스트") - void testFindRegionByNameFail() { - // given - when(regionRepository.findFirstByName(region1.getName())).thenThrow(new RegionNotFoundException()); - - // when & then - Assertions.assertThrows(RegionNotFoundException.class, () -> { - regionService.findRegionByName(region1.getName()); - }); - - verify(regionRepository, times(1)).findFirstByName(region1.getName()); - } -} diff --git a/src/test/java/taco/klkl/domain/region/service/CityServiceImplTest.java b/src/test/java/taco/klkl/domain/region/service/city/CityServiceImplTest.java similarity index 93% rename from src/test/java/taco/klkl/domain/region/service/CityServiceImplTest.java rename to src/test/java/taco/klkl/domain/region/service/city/CityServiceImplTest.java index 1cd6ab6e..5710c329 100644 --- a/src/test/java/taco/klkl/domain/region/service/CityServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/region/service/city/CityServiceImplTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.region.service; +package taco.klkl.domain.region.service.city; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -18,7 +18,6 @@ import taco.klkl.domain.region.domain.city.CityType; import taco.klkl.domain.region.domain.country.Country; import taco.klkl.domain.region.dto.response.city.CityResponse; -import taco.klkl.domain.region.service.city.CityServiceImpl; @ExtendWith(MockitoExtension.class) public class CityServiceImplTest { diff --git a/src/test/java/taco/klkl/domain/region/service/country/CountryServiceImplTest.java b/src/test/java/taco/klkl/domain/region/service/country/CountryServiceImplTest.java new file mode 100644 index 00000000..ba0aa23f --- /dev/null +++ b/src/test/java/taco/klkl/domain/region/service/country/CountryServiceImplTest.java @@ -0,0 +1,79 @@ +package taco.klkl.domain.region.service.country; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import taco.klkl.domain.region.dao.country.CountryRepository; +import taco.klkl.domain.region.domain.country.Country; +import taco.klkl.domain.region.domain.country.CountryType; +import taco.klkl.domain.region.domain.currency.Currency; +import taco.klkl.domain.region.domain.currency.CurrencyType; +import taco.klkl.domain.region.domain.region.Region; +import taco.klkl.domain.region.domain.region.RegionType; +import taco.klkl.domain.region.dto.response.country.CountryResponse; +import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; + +@ExtendWith(MockitoExtension.class) +public class CountryServiceImplTest { + + @InjectMocks + CountryServiceImpl countryService; + + @Mock + CountryRepository countryRepository; + + private final Region region = Region.from(RegionType.NORTHEAST_ASIA); + private final Currency currency1 = Currency.of(CurrencyType.JAPANESE_YEN); + private final Country country1 = Country.of( + CountryType.JAPAN, + region, + "wallpaper", + currency1); + private final Country country2 = Country.of( + CountryType.TAIWAN, + region, + "wallpaper", + currency1); + + @Test + @DisplayName("id로 국가조회 테스트") + void testFindCountryById() { + // given + when(countryRepository.findById(400L)).thenReturn(Optional.of(country1)); + + // when + CountryResponse findCountry = countryService.getCountryById(400L); + + // then + assertThat(findCountry).isEqualTo(CountryResponse.from(country1)); + } + + @Test + @DisplayName("부분 문자열로 국가 조회") + void testGetCountriesByCountryTypes() { + // given + String partialName = "foo"; + CountrySimpleResponse country1ResponseDto = CountrySimpleResponse.from(country1); + CountrySimpleResponse country2ResponseDto = CountrySimpleResponse.from(country2); + when(countryRepository.findAllByNameContaining(partialName)).thenReturn(Arrays.asList(country1, country2)); + + // when + List countryWithCitiesResponse = countryService.findAllCountriesByPartialString( + partialName); + + // then + assertThat(countryWithCitiesResponse).hasSize(2); + assertThat(countryWithCitiesResponse).containsExactlyInAnyOrder(country1ResponseDto, country2ResponseDto); + } +} diff --git a/src/test/java/taco/klkl/domain/region/service/CurrencyServiceImplTest.java b/src/test/java/taco/klkl/domain/region/service/currency/CurrencyServiceImplTest.java similarity index 93% rename from src/test/java/taco/klkl/domain/region/service/CurrencyServiceImplTest.java rename to src/test/java/taco/klkl/domain/region/service/currency/CurrencyServiceImplTest.java index 70a2ca2b..f54561a8 100644 --- a/src/test/java/taco/klkl/domain/region/service/CurrencyServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/region/service/currency/CurrencyServiceImplTest.java @@ -1,4 +1,4 @@ -package taco.klkl.domain.region.service; +package taco.klkl.domain.region.service.currency; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -17,7 +17,6 @@ import taco.klkl.domain.region.domain.currency.Currency; import taco.klkl.domain.region.domain.currency.CurrencyType; import taco.klkl.domain.region.dto.response.currency.CurrencyResponse; -import taco.klkl.domain.region.service.currency.CurrencyServiceImpl; @ExtendWith(MockitoExtension.class) public class CurrencyServiceImplTest { diff --git a/src/test/java/taco/klkl/domain/region/service/region/RegionServiceImplTest.java b/src/test/java/taco/klkl/domain/region/service/region/RegionServiceImplTest.java new file mode 100644 index 00000000..cc33e6fb --- /dev/null +++ b/src/test/java/taco/klkl/domain/region/service/region/RegionServiceImplTest.java @@ -0,0 +1,65 @@ +package taco.klkl.domain.region.service.region; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import taco.klkl.domain.region.dao.region.RegionRepository; +import taco.klkl.domain.region.domain.region.Region; +import taco.klkl.domain.region.domain.region.RegionType; +import taco.klkl.domain.region.dto.response.region.RegionResponse; + +@ExtendWith(MockitoExtension.class) +class RegionServiceImplTest { + + @InjectMocks + RegionServiceImpl regionService; + + @Mock + RegionRepository regionRepository; + + private final Region region1 = Region.from(RegionType.NORTHEAST_ASIA); + private final Region region2 = Region.from(RegionType.SOUTHEAST_ASIA); + private final Region region3 = Region.from(RegionType.ETC); + + @Test + @DisplayName("모든 지역 조회 성공 테스트") + void testGetAllRegion() { + // given + List mockRegions = Arrays.asList(region1, region2, region3); + + when(regionRepository.findAllByOrderByIdAsc()).thenReturn(mockRegions); + + // when + List regionResponses = regionService.findAllRegions(); + + // then + assertThat(regionResponses.size()).isEqualTo(3); + assertThat(regionResponses.get(0).name()).isEqualTo(region1.getName()); + assertThat(regionResponses.get(1).name()).isEqualTo(region2.getName()); + assertThat(regionResponses.get(2).name()).isEqualTo(region3.getName()); + } + + @Test + @DisplayName("모든 지역 조회 실패 테스트") + void testGetAllRegionFail() { + // given + when(regionRepository.findAllByOrderByIdAsc()).thenReturn(Collections.emptyList()); + + // when + List regionResponses = regionService.findAllRegions(); + + // then + assertThat(regionResponses.size()).isEqualTo(0); + } +} diff --git a/src/test/java/taco/klkl/domain/search/controller/SearchControllerTest.java b/src/test/java/taco/klkl/domain/search/controller/SearchControllerTest.java index 6f911c54..7bf0205a 100644 --- a/src/test/java/taco/klkl/domain/search/controller/SearchControllerTest.java +++ b/src/test/java/taco/klkl/domain/search/controller/SearchControllerTest.java @@ -28,6 +28,7 @@ import taco.klkl.domain.region.domain.region.Region; import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; +import taco.klkl.domain.region.dto.response.country.CountryWithCitiesResponse; import taco.klkl.domain.search.dto.response.SearchResponse; import taco.klkl.domain.search.service.SearchService; @@ -48,7 +49,7 @@ public class SearchControllerTest { @Mock Currency currency; - private final Country country = Country.of(CountryType.MALAYSIA, region, "photo", currency); + private final Country country = Country.of(CountryType.MALAYSIA, region, "wallpaper", currency); private final City city = City.of(CityType.BORACAY, country); private final Category category = Category.of(CategoryType.CLOTHES); private final Subcategory subcategory = Subcategory.of(category, SubcategoryType.MAKEUP); diff --git a/src/test/java/taco/klkl/domain/search/service/SearchServiceImplTest.java b/src/test/java/taco/klkl/domain/search/service/SearchServiceImplTest.java index 4fc07370..00c69b27 100644 --- a/src/test/java/taco/klkl/domain/search/service/SearchServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/search/service/SearchServiceImplTest.java @@ -29,6 +29,7 @@ import taco.klkl.domain.region.domain.region.Region; import taco.klkl.domain.region.dto.response.city.CityResponse; import taco.klkl.domain.region.dto.response.country.CountrySimpleResponse; +import taco.klkl.domain.region.dto.response.country.CountryWithCitiesResponse; import taco.klkl.domain.region.service.city.CityService; import taco.klkl.domain.region.service.country.CountryService; import taco.klkl.domain.search.dto.response.SearchResponse; @@ -57,7 +58,7 @@ class SearchServiceImplTest { @Mock Currency currency; - private final Country country = Country.of(CountryType.MALAYSIA, region, "photo", currency); + private final Country country = Country.of(CountryType.MALAYSIA, region, "wallpaper", currency); private final City city = City.of(CityType.BORACAY, country); private final Category category = Category.of(CategoryType.CLOTHES); private final Subcategory subcategory = Subcategory.of(category, SubcategoryType.MAKEUP); diff --git a/src/test/java/taco/klkl/domain/user/controller/UserControllerTest.java b/src/test/java/taco/klkl/domain/user/controller/UserControllerTest.java index 047aea50..7aedc7c5 100644 --- a/src/test/java/taco/klkl/domain/user/controller/UserControllerTest.java +++ b/src/test/java/taco/klkl/domain/user/controller/UserControllerTest.java @@ -54,10 +54,8 @@ public void testGetMe() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data.id", is(nullValue()))) - .andExpect(jsonPath("$.data.profileUrl", is(userDetailResponse.profileUrl()))) .andExpect(jsonPath("$.data.name", is(userDetailResponse.name()))) .andExpect(jsonPath("$.data.description", is(userDetailResponse.description()))) - .andExpect(jsonPath("$.data.totalLikeCount", is(UserConstants.DEFAULT_TOTAL_LIKE_COUNT))) .andExpect(jsonPath("$.timestamp", notNullValue())); } } diff --git a/src/test/java/taco/klkl/domain/user/dto/response/UserDetailResponseTest.java b/src/test/java/taco/klkl/domain/user/dto/response/UserDetailResponseTest.java index 49d3b906..d97ef8ce 100644 --- a/src/test/java/taco/klkl/domain/user/dto/response/UserDetailResponseTest.java +++ b/src/test/java/taco/klkl/domain/user/dto/response/UserDetailResponseTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.user.domain.User; import taco.klkl.global.common.constants.UserConstants; @@ -14,20 +15,18 @@ public class UserDetailResponseTest { public void testUserDetailResponseDto() { // given Long id = 1L; - String profile = "image/profileUrl.png"; + ImageResponse image = new ImageResponse(2L, "url"); String name = "이름"; String description = "자기소개"; - int totalLikeCount = 100; // when - UserDetailResponse userDetail = new UserDetailResponse(id, profile, name, description, totalLikeCount); + UserDetailResponse userDetail = new UserDetailResponse(id, image, name, description); // then assertThat(userDetail.id()).isEqualTo(id); - assertThat(userDetail.profileUrl()).isEqualTo(profile); + assertThat(userDetail.image().id()).isEqualTo(image.id()); assertThat(userDetail.name()).isEqualTo(name); assertThat(userDetail.description()).isEqualTo(description); - assertThat(userDetail.totalLikeCount()).isEqualTo(totalLikeCount); } @Test @@ -44,6 +43,5 @@ public void testFrom() { // then assertThat(userDetail.name()).isEqualTo(name); assertThat(userDetail.description()).isEqualTo(description); - assertThat(userDetail.totalLikeCount()).isEqualTo(UserConstants.DEFAULT_TOTAL_LIKE_COUNT); } } diff --git a/src/test/java/taco/klkl/domain/user/dto/response/UserSimpleResponseTest.java b/src/test/java/taco/klkl/domain/user/dto/response/UserSimpleResponseTest.java index a1e4243d..79b98464 100644 --- a/src/test/java/taco/klkl/domain/user/dto/response/UserSimpleResponseTest.java +++ b/src/test/java/taco/klkl/domain/user/dto/response/UserSimpleResponseTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import taco.klkl.domain.image.dto.response.ImageResponse; import taco.klkl.domain.user.domain.User; class UserSimpleResponseTest { @@ -13,15 +14,15 @@ class UserSimpleResponseTest { public void testUserSimpleResponseDto() { // given Long id = 1L; - String profile = "image/profileUrl.png"; + ImageResponse image = new ImageResponse(2L, "url"); String name = "이름"; // when - UserSimpleResponse userSimple = new UserSimpleResponse(id, profile, name); + UserSimpleResponse userSimple = new UserSimpleResponse(id, image, name); // then assertThat(userSimple.id()).isEqualTo(id); - assertThat(userSimple.profileUrl()).isEqualTo(profile); + assertThat(userSimple.image().id()).isEqualTo(image.id()); assertThat(userSimple.name()).isEqualTo(name); } diff --git a/src/test/java/taco/klkl/domain/user/integration/UserIntegrationTest.java b/src/test/java/taco/klkl/domain/user/integration/UserIntegrationTest.java index f04a794a..ecebe610 100644 --- a/src/test/java/taco/klkl/domain/user/integration/UserIntegrationTest.java +++ b/src/test/java/taco/klkl/domain/user/integration/UserIntegrationTest.java @@ -44,7 +44,6 @@ public void testUserMe() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data.id", is(currentUser.id().intValue()))) - .andExpect(jsonPath("$.data.profileUrl", is(currentUser.profileUrl()))) .andExpect(jsonPath("$.data.name", is(currentUser.name()))) .andExpect(jsonPath("$.data.description", is(currentUser.description()))) .andExpect(jsonPath("$.timestamp", notNullValue())) diff --git a/src/test/java/taco/klkl/domain/user/service/UserServiceImplTest.java b/src/test/java/taco/klkl/domain/user/service/UserServiceImplTest.java index 19d4413e..9ce5c1ce 100644 --- a/src/test/java/taco/klkl/domain/user/service/UserServiceImplTest.java +++ b/src/test/java/taco/klkl/domain/user/service/UserServiceImplTest.java @@ -52,7 +52,6 @@ public void testGetUserById() { assertThat(userDto.id()).isEqualTo(user.getId()); assertThat(userDto.name()).isEqualTo(user.getName()); assertThat(userDto.description()).isEqualTo(user.getDescription()); - assertThat(userDto.totalLikeCount()).isEqualTo(UserConstants.DEFAULT_TOTAL_LIKE_COUNT); } @Test @@ -76,6 +75,5 @@ public void testCreateUser() { // then assertThat(responseDto.name()).isEqualTo(requestDto.name()); assertThat(responseDto.description()).isEqualTo(requestDto.description()); - assertThat(responseDto.totalLikeCount()).isEqualTo(UserConstants.DEFAULT_TOTAL_LIKE_COUNT); } }