From 201232d2fd74ef5ae2461c67b1f96f8282e697ea Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 11:43:12 +0900 Subject: [PATCH 01/30] =?UTF-8?q?[#54]=20feat:=20experience=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/repository/CategoryRepository.java | 10 ++++ .../controller/ExperienceController.java | 29 +++++++++++ .../experience/dto/ExperienceRequest.java | 13 +++++ .../experience/dto/ExperienceResponse.java | 5 ++ .../experience/service/ExperienceService.java | 52 +++++++++++++++++++ .../repository/FavoriteRepository.java | 13 +++++ .../global/exception/SuccessCode.java | 5 +- .../service/ExperienceServiceTest.java | 5 ++ 8 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java create mode 100644 src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java create mode 100644 src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceRequest.java create mode 100644 src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceResponse.java create mode 100644 src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java create mode 100644 src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java create mode 100644 src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java diff --git a/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java b/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java new file mode 100644 index 00000000..dac20de3 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java @@ -0,0 +1,10 @@ +package com.jeju.nanaland.domain.common.repository; + +import com.jeju.nanaland.domain.common.entity.Category; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CategoryRepository extends JpaRepository { + + public Optional findByContent(String content); +} diff --git a/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java b/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java new file mode 100644 index 00000000..8e3e2e4a --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java @@ -0,0 +1,29 @@ +package com.jeju.nanaland.domain.experience.controller; + +import static com.jeju.nanaland.global.exception.SuccessCode.POST_LIKE_TOGGLE_SUCCESS; + +import com.jeju.nanaland.domain.experience.service.ExperienceService; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.BaseResponse; +import com.jeju.nanaland.global.jwt.AuthMember; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/experience") +@RequiredArgsConstructor +@Slf4j +public class ExperienceController { + + private final ExperienceService experienceService; + + @PostMapping("/like/{id}") + public BaseResponse toggleLikeStatus(@AuthMember Member member, @PathVariable Long id) { + String result = experienceService.toggleLikeStatus(member, id); + return BaseResponse.success(POST_LIKE_TOGGLE_SUCCESS, result); + } +} diff --git a/src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceRequest.java b/src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceRequest.java new file mode 100644 index 00000000..3794c9bc --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceRequest.java @@ -0,0 +1,13 @@ +package com.jeju.nanaland.domain.experience.dto; + +import lombok.Data; + +public class ExperienceRequest { + + @Data + public static class LikeDto { + + private Long postId; + + } +} diff --git a/src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceResponse.java b/src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceResponse.java new file mode 100644 index 00000000..b1bd9b04 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/experience/dto/ExperienceResponse.java @@ -0,0 +1,5 @@ +package com.jeju.nanaland.domain.experience.dto; + +public class ExperienceResponse { + +} diff --git a/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java b/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java new file mode 100644 index 00000000..0320141d --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java @@ -0,0 +1,52 @@ +package com.jeju.nanaland.domain.experience.service; + +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.repository.CategoryRepository; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.exception.ServerErrorException; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Slf4j +public class ExperienceService { + + private final CategoryRepository categoryRepository; + private final FavoriteRepository favoriteRepository; + + @Transactional + public String toggleLikeStatus(Member member, Long postId) { + Category experienceCategory = categoryRepository.findByContent("EXPERIENCE") + .orElseThrow(() -> new ServerErrorException("EXPERIENCE에 해당하는 카테고리가 없습니다.")); + + Optional favoriteOptional = favoriteRepository.findByMemberAndCategoryAndPostId( + member, experienceCategory, postId); + + // 좋아요 상태일 때 + if (favoriteOptional.isPresent()) { + Favorite favorite = favoriteOptional.get(); + + // 좋아요 삭제 + favoriteRepository.delete(favorite); + return "좋아요 삭제"; + } + // 좋아요 상태가 아닐 때 + else { + Favorite favorite = Favorite.builder() + .member(member) + .category(experienceCategory) + .postId(postId) + .build(); + + // 좋아요 추가 + favoriteRepository.save(favorite); + return "좋아요 추가"; + } + } +} diff --git a/src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java b/src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java new file mode 100644 index 00000000..f3b048b3 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java @@ -0,0 +1,13 @@ +package com.jeju.nanaland.domain.favorite.repository; + +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.member.entity.Member; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FavoriteRepository extends JpaRepository { + + public Optional findByMemberAndCategoryAndPostId(Member member, Category category, + Long postId); +} diff --git a/src/main/java/com/jeju/nanaland/global/exception/SuccessCode.java b/src/main/java/com/jeju/nanaland/global/exception/SuccessCode.java index edf59ed5..124f96d8 100644 --- a/src/main/java/com/jeju/nanaland/global/exception/SuccessCode.java +++ b/src/main/java/com/jeju/nanaland/global/exception/SuccessCode.java @@ -28,7 +28,10 @@ public enum SuccessCode { // nana NANA_MAIN_SUCCESS(OK, "나나 메인 페이지 썸네일 조회 성공"), NANA_LIST_SUCCESS(OK, "나나 썸네일 리스트 조회 성공"), - NANA_DETAIL_SUCCESS(OK, "나나 상세 페이지 조회 성공"); + NANA_DETAIL_SUCCESS(OK, "나나 상세 페이지 조회 성공"), + + // favorite + POST_LIKE_TOGGLE_SUCCESS(OK, "게시물 좋아요 토글 요청 성공"); private final HttpStatus httpStatus; private final String message; diff --git a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java new file mode 100644 index 00000000..f792ee6d --- /dev/null +++ b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java @@ -0,0 +1,5 @@ +package com.jeju.nanaland.domain.experience.service; + +class ExperienceServiceTest { + +} \ No newline at end of file From 18d4980909d474e016f1dcffadfbdd475101c58a Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 12:42:39 +0900 Subject: [PATCH 02/30] [#54] feat: experience like toggle test --- .../service/ExperienceServiceTest.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java index f792ee6d..9dfc8e37 100644 --- a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java @@ -1,5 +1,115 @@ package com.jeju.nanaland.domain.experience.service; +import static org.assertj.core.api.Assertions.assertThat; + +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.entity.ImageFile; +import com.jeju.nanaland.domain.common.entity.Language; +import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.experience.entity.Experience; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.member.entity.Provider; +import jakarta.persistence.EntityManager; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional class ExperienceServiceTest { + @Autowired + EntityManager em; + @Autowired + ExperienceService experienceService; + @Autowired + FavoriteRepository favoriteRepository; + + Language language; + Member member1, member2; + Experience experience; + Category category; + + @BeforeEach + void init() { + ImageFile imageFile1 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile1); + + ImageFile imageFile2 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile2); + + language = Language.builder() + .locale(Locale.KOREAN) + .dateFormat("yy-mm-dd") + .build(); + em.persist(language); + + member1 = Member.builder() + .email("test@naver.com") + .provider(Provider.KAKAO) + .providerId(123456789L) + .nickname("nickname1") + .language(language) + .profileImageFile(imageFile1) + .build(); + em.persist(member1); + + member2 = Member.builder() + .email("test2@naver.com") + .provider(Provider.KAKAO) + .providerId(1234567890L) + .nickname("nickname2") + .language(language) + .profileImageFile(imageFile2) + .build(); + em.persist(member2); + + experience = Experience.builder() + .imageFile(imageFile1) + .build(); + em.persist(experience); + + category = Category.builder() + .content("EXPERIENCE") + .build(); + em.persist(category); + } + + @Test + void toggleLikeStatusTest() { + /** + * WHEN + * + * member1 : toggleLikeStatus 2번 적용 + * member2 : toggleLikeStatus 1번 적용 + */ + experienceService.toggleLikeStatus(member1, experience.getId()); + experienceService.toggleLikeStatus(member1, experience.getId()); + + experienceService.toggleLikeStatus(member2, experience.getId()); + + Optional favoriteOptional1 = + favoriteRepository.findByMemberAndCategoryAndPostId(member1, category, experience.getId()); + Optional favoriteOptional2 = + favoriteRepository.findByMemberAndCategoryAndPostId(member2, category, experience.getId()); + + /** + * THEN + * + * member1 = 좋아요 X, member2 = 좋아요 + */ + assertThat(favoriteOptional1.isPresent()).isFalse(); + assertThat(favoriteOptional2.isPresent()).isTrue(); + } } \ No newline at end of file From a0dc2bf5c9a652d45d87b8dee04dac053f7b0971 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 12:46:57 +0900 Subject: [PATCH 03/30] [#54] feat: experience swagger --- .../controller/ExperienceController.java | 12 ++++++++++++ .../festival/controller/FestivalController.java | 14 ++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java diff --git a/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java b/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java index 8e3e2e4a..87674414 100644 --- a/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java +++ b/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java @@ -6,6 +6,11 @@ import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.global.BaseResponse; import com.jeju.nanaland.global.jwt.AuthMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PathVariable; @@ -17,10 +22,17 @@ @RequestMapping("/experience") @RequiredArgsConstructor @Slf4j +@Tag(name = "이색체험(Experience)", description = "이색체험(Experience) API입니다.") public class ExperienceController { private final ExperienceService experienceService; + @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) + }) @PostMapping("/like/{id}") public BaseResponse toggleLikeStatus(@AuthMember Member member, @PathVariable Long id) { String result = experienceService.toggleLikeStatus(member, id); diff --git a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java new file mode 100644 index 00000000..f5d31bfd --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java @@ -0,0 +1,14 @@ +package com.jeju.nanaland.domain.festival.controller; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/festival") +@Slf4j +public class FestivalController { + +} From ca1d4b42d9362d10fff6a9be14919faeb0ed2e24 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:15:08 +0900 Subject: [PATCH 04/30] =?UTF-8?q?[#54]=20feat:=20experience=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/data/CategoryContent.java | 9 +++ .../domain/common/entity/Category.java | 10 ++- .../common/repository/CategoryRepository.java | 3 +- .../experience/service/ExperienceService.java | 38 +--------- .../favorite/service/FavoriteService.java | 74 +++++++++++++++++++ .../festival/service/FestivalService.java | 17 +++++ .../entity/EntityImageFileMappingTest.java | 3 +- .../service/ExperienceServiceTest.java | 3 +- 8 files changed, 117 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/jeju/nanaland/domain/common/data/CategoryContent.java create mode 100644 src/main/java/com/jeju/nanaland/domain/favorite/service/FavoriteService.java create mode 100644 src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java diff --git a/src/main/java/com/jeju/nanaland/domain/common/data/CategoryContent.java b/src/main/java/com/jeju/nanaland/domain/common/data/CategoryContent.java new file mode 100644 index 00000000..f87c9e32 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/common/data/CategoryContent.java @@ -0,0 +1,9 @@ +package com.jeju.nanaland.domain.common.data; + +public enum CategoryContent { + NANA, + EXPERIENCE, + FESTIVAL, + NATURE, + MARKET +} diff --git a/src/main/java/com/jeju/nanaland/domain/common/entity/Category.java b/src/main/java/com/jeju/nanaland/domain/common/entity/Category.java index 2057810a..5167405d 100644 --- a/src/main/java/com/jeju/nanaland/domain/common/entity/Category.java +++ b/src/main/java/com/jeju/nanaland/domain/common/entity/Category.java @@ -1,8 +1,11 @@ package com.jeju.nanaland.domain.common.entity; +import com.jeju.nanaland.domain.common.data.CategoryContent; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.validation.constraints.NotBlank; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -16,7 +19,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Category extends BaseEntity { - @NotBlank + @NotNull @Column(nullable = false, unique = true) - private String content; + @Enumerated(EnumType.STRING) + private CategoryContent content; } diff --git a/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java b/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java index dac20de3..b5c6b132 100644 --- a/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java +++ b/src/main/java/com/jeju/nanaland/domain/common/repository/CategoryRepository.java @@ -1,10 +1,11 @@ package com.jeju.nanaland.domain.common.repository; +import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.common.entity.Category; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface CategoryRepository extends JpaRepository { - public Optional findByContent(String content); + public Optional findByContent(CategoryContent content); } diff --git a/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java b/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java index 0320141d..a7f818ed 100644 --- a/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java +++ b/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java @@ -1,12 +1,8 @@ package com.jeju.nanaland.domain.experience.service; -import com.jeju.nanaland.domain.common.entity.Category; -import com.jeju.nanaland.domain.common.repository.CategoryRepository; -import com.jeju.nanaland.domain.favorite.entity.Favorite; -import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.favorite.service.FavoriteService; import com.jeju.nanaland.domain.member.entity.Member; -import com.jeju.nanaland.global.exception.ServerErrorException; -import java.util.Optional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -17,36 +13,10 @@ @Slf4j public class ExperienceService { - private final CategoryRepository categoryRepository; - private final FavoriteRepository favoriteRepository; + private final FavoriteService favoriteService; @Transactional public String toggleLikeStatus(Member member, Long postId) { - Category experienceCategory = categoryRepository.findByContent("EXPERIENCE") - .orElseThrow(() -> new ServerErrorException("EXPERIENCE에 해당하는 카테고리가 없습니다.")); - - Optional favoriteOptional = favoriteRepository.findByMemberAndCategoryAndPostId( - member, experienceCategory, postId); - - // 좋아요 상태일 때 - if (favoriteOptional.isPresent()) { - Favorite favorite = favoriteOptional.get(); - - // 좋아요 삭제 - favoriteRepository.delete(favorite); - return "좋아요 삭제"; - } - // 좋아요 상태가 아닐 때 - else { - Favorite favorite = Favorite.builder() - .member(member) - .category(experienceCategory) - .postId(postId) - .build(); - - // 좋아요 추가 - favoriteRepository.save(favorite); - return "좋아요 추가"; - } + return favoriteService.toggleLikeStatus(member, CategoryContent.EXPERIENCE, postId); } } diff --git a/src/main/java/com/jeju/nanaland/domain/favorite/service/FavoriteService.java b/src/main/java/com/jeju/nanaland/domain/favorite/service/FavoriteService.java new file mode 100644 index 00000000..407143a0 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/favorite/service/FavoriteService.java @@ -0,0 +1,74 @@ +package com.jeju.nanaland.domain.favorite.service; + +import static com.jeju.nanaland.domain.common.data.CategoryContent.EXPERIENCE; +import static com.jeju.nanaland.domain.common.data.CategoryContent.FESTIVAL; +import static com.jeju.nanaland.domain.common.data.CategoryContent.MARKET; +import static com.jeju.nanaland.domain.common.data.CategoryContent.NANA; +import static com.jeju.nanaland.domain.common.data.CategoryContent.NATURE; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.repository.CategoryRepository; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.exception.ServerErrorException; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Slf4j +public class FavoriteService { + + private final CategoryRepository categoryRepository; + private final FavoriteRepository favoriteRepository; + + @Transactional + public String toggleLikeStatus(Member member, CategoryContent categoryContent, Long postId) { + + Category category = switch (categoryContent) { + case NANA -> categoryRepository.findByContent(NANA) + .orElseThrow(() -> new ServerErrorException("NANA에 해당하는 카테고리가 없습니다.")); + + case EXPERIENCE -> categoryRepository.findByContent(EXPERIENCE) + .orElseThrow(() -> new ServerErrorException("EXPERIENCE에 해당하는 카테고리가 없습니다.")); + + case NATURE -> categoryRepository.findByContent(NATURE) + .orElseThrow(() -> new ServerErrorException("NATURE에 해당하는 카테고리가 없습니다.")); + + case MARKET -> categoryRepository.findByContent(MARKET) + .orElseThrow(() -> new ServerErrorException("MARKET에 해당하는 카테고리가 없습니다.")); + + case FESTIVAL -> categoryRepository.findByContent(FESTIVAL) + .orElseThrow(() -> new ServerErrorException("FESTIVAL에 해당하는 카테고리가 없습니다.")); + }; + + Optional favoriteOptional = favoriteRepository.findByMemberAndCategoryAndPostId( + member, category, postId); + + // 좋아요 상태일 때 + if (favoriteOptional.isPresent()) { + Favorite favorite = favoriteOptional.get(); + + // 좋아요 삭제 + favoriteRepository.delete(favorite); + return "좋아요 삭제"; + } + // 좋아요 상태가 아닐 때 + else { + Favorite favorite = Favorite.builder() + .member(member) + .category(category) + .postId(postId) + .build(); + + // 좋아요 추가 + favoriteRepository.save(favorite); + return "좋아요 추가"; + } + } +} diff --git a/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java b/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java new file mode 100644 index 00000000..a08f1d34 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java @@ -0,0 +1,17 @@ +package com.jeju.nanaland.domain.festival.service; + +import com.jeju.nanaland.domain.common.repository.CategoryRepository; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class FestivalService { + + private final CategoryRepository categoryRepository; + private final FavoriteRepository favoriteRepository; + +} diff --git a/src/test/java/com/jeju/nanaland/domain/entity/EntityImageFileMappingTest.java b/src/test/java/com/jeju/nanaland/domain/entity/EntityImageFileMappingTest.java index 594a27c4..53592761 100644 --- a/src/test/java/com/jeju/nanaland/domain/entity/EntityImageFileMappingTest.java +++ b/src/test/java/com/jeju/nanaland/domain/entity/EntityImageFileMappingTest.java @@ -1,6 +1,7 @@ package com.jeju.nanaland.domain.entity; +import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.common.entity.Category; import com.jeju.nanaland.domain.common.entity.ImageFile; import com.jeju.nanaland.domain.common.entity.Language; @@ -94,7 +95,7 @@ void reviewImageFileMapping() { em.persist(keyword); Category category = Category.builder() - .content("content") + .content(CategoryContent.EXPERIENCE) .build(); em.persist(category); diff --git a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java index 9dfc8e37..72309565 100644 --- a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.common.entity.Category; import com.jeju.nanaland.domain.common.entity.ImageFile; import com.jeju.nanaland.domain.common.entity.Language; @@ -81,7 +82,7 @@ void init() { em.persist(experience); category = Category.builder() - .content("EXPERIENCE") + .content(CategoryContent.EXPERIENCE) .build(); em.persist(category); } From 2457392ad24737e3ba5b507e6d9c14eb578d3c30 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:17:16 +0900 Subject: [PATCH 05/30] =?UTF-8?q?[#54]=20feat:=20festival=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FestivalController.java | 25 +++++++++++++++++++ .../festival/service/FestivalService.java | 13 +++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java index f5d31bfd..e3dc655e 100644 --- a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java +++ b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java @@ -1,7 +1,19 @@ package com.jeju.nanaland.domain.festival.controller; +import static com.jeju.nanaland.global.exception.SuccessCode.POST_LIKE_TOGGLE_SUCCESS; + +import com.jeju.nanaland.domain.festival.service.FestivalService; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.BaseResponse; +import com.jeju.nanaland.global.jwt.AuthMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -11,4 +23,17 @@ @Slf4j public class FestivalController { + private final FestivalService festivalService; + + @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) + }) + @PostMapping("/like/{id}") + public BaseResponse toggleLikeStatus(@AuthMember Member member, @PathVariable Long id) { + String result = festivalService.toggleLikeStatus(member, id); + return BaseResponse.success(POST_LIKE_TOGGLE_SUCCESS, result); + } } diff --git a/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java b/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java index a08f1d34..01520790 100644 --- a/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java +++ b/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java @@ -1,17 +1,22 @@ package com.jeju.nanaland.domain.festival.service; -import com.jeju.nanaland.domain.common.repository.CategoryRepository; -import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.member.entity.Member; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @Slf4j public class FestivalService { - private final CategoryRepository categoryRepository; - private final FavoriteRepository favoriteRepository; + private final FavoriteService favoriteService; + @Transactional + public String toggleLikeStatus(Member member, Long postId) { + return favoriteService.toggleLikeStatus(member, CategoryContent.FESTIVAL, postId); + } } From 13d1590025cffe110de2149d77dd864162e2163a Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:20:22 +0900 Subject: [PATCH 06/30] [#54] feat: festival like test --- .../festival/service/FestivalServiceTest.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java diff --git a/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java b/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java new file mode 100644 index 00000000..5b24d9a0 --- /dev/null +++ b/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java @@ -0,0 +1,116 @@ +package com.jeju.nanaland.domain.festival.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.entity.ImageFile; +import com.jeju.nanaland.domain.common.entity.Language; +import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.festival.entity.Festival; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.member.entity.Provider; +import jakarta.persistence.EntityManager; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class FestivalServiceTest { + + @Autowired + EntityManager em; + @Autowired + FestivalService festivalService; + @Autowired + FavoriteRepository favoriteRepository; + + Language language; + Member member1, member2; + Festival festival; + Category category; + + @BeforeEach + void init() { + ImageFile imageFile1 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile1); + + ImageFile imageFile2 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile2); + + language = Language.builder() + .locale(Locale.KOREAN) + .dateFormat("yy-mm-dd") + .build(); + em.persist(language); + + member1 = Member.builder() + .email("test@naver.com") + .provider(Provider.KAKAO) + .providerId(123456789L) + .nickname("nickname1") + .language(language) + .profileImageFile(imageFile1) + .build(); + em.persist(member1); + + member2 = Member.builder() + .email("test2@naver.com") + .provider(Provider.KAKAO) + .providerId(1234567890L) + .nickname("nickname2") + .language(language) + .profileImageFile(imageFile2) + .build(); + em.persist(member2); + + festival = Festival.builder() + .imageFile(imageFile1) + .build(); + em.persist(festival); + + category = Category.builder() + .content(CategoryContent.FESTIVAL) + .build(); + em.persist(category); + } + + @Test + void toggleLikeStatusTest() { + /** + * WHEN + * + * member1 : toggleLikeStatus 2번 적용 + * member2 : toggleLikeStatus 1번 적용 + */ + festivalService.toggleLikeStatus(member1, festival.getId()); + festivalService.toggleLikeStatus(member1, festival.getId()); + + festivalService.toggleLikeStatus(member2, festival.getId()); + + Optional favoriteOptional1 = + favoriteRepository.findByMemberAndCategoryAndPostId(member1, category, festival.getId()); + Optional favoriteOptional2 = + favoriteRepository.findByMemberAndCategoryAndPostId(member2, category, festival.getId()); + + /** + * THEN + * + * member1 = 좋아요 X, member2 = 좋아요 + */ + assertThat(favoriteOptional1.isPresent()).isFalse(); + assertThat(favoriteOptional2.isPresent()).isTrue(); + } +} \ No newline at end of file From ecbdbf4837e1bb386ab7acc1ad4d8ed86098c9e4 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:21:08 +0900 Subject: [PATCH 07/30] [#54] feat: festival swagger --- .../nanaland/domain/festival/controller/FestivalController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java index e3dc655e..1d964d9e 100644 --- a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java +++ b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java @@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PathVariable; @@ -21,6 +22,7 @@ @RequiredArgsConstructor @RequestMapping("/festival") @Slf4j +@Tag(name = "축제(Festival)", description = "축제(Festival) API입니다.") public class FestivalController { private final FestivalService festivalService; From 44226408e55a0555963c6c51e16160abf42493f4 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:23:28 +0900 Subject: [PATCH 08/30] =?UTF-8?q?[#54]=20feat:=20market=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../market/controller/MarketController.java | 41 +++++++++++++++++++ .../domain/market/service/MarketService.java | 22 ++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java create mode 100644 src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java diff --git a/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java b/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java new file mode 100644 index 00000000..e78b4c40 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java @@ -0,0 +1,41 @@ +package com.jeju.nanaland.domain.market.controller; + +import static com.jeju.nanaland.global.exception.SuccessCode.POST_LIKE_TOGGLE_SUCCESS; + +import com.jeju.nanaland.domain.market.service.MarketService; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.BaseResponse; +import com.jeju.nanaland.global.jwt.AuthMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/market") +@Slf4j +@Tag(name = "전통시장(Market)", description = "전통시장(Market) API입니다.") +public class MarketController { + + private final MarketService marketService; + + @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) + }) + @PostMapping("/like/{id}") + public BaseResponse toggleLikeStatus(@AuthMember Member member, @PathVariable Long id) { + String result = marketService.toggleLikeStatus(member, id); + return BaseResponse.success(POST_LIKE_TOGGLE_SUCCESS, result); + } +} diff --git a/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java b/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java new file mode 100644 index 00000000..8d1dd6da --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java @@ -0,0 +1,22 @@ +package com.jeju.nanaland.domain.market.service; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.member.entity.Member; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Slf4j +public class MarketService { + + private final FavoriteService favoriteService; + + @Transactional + public String toggleLikeStatus(Member member, Long postId) { + return favoriteService.toggleLikeStatus(member, CategoryContent.MARKET, postId); + } +} From bade98863945e182b004bb93a939c8562a76a644 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:25:48 +0900 Subject: [PATCH 09/30] [#54] feat: market like test --- .../market/service/MarketServiceTest.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java diff --git a/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java b/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java new file mode 100644 index 00000000..fb13c991 --- /dev/null +++ b/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java @@ -0,0 +1,116 @@ +package com.jeju.nanaland.domain.market.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.entity.ImageFile; +import com.jeju.nanaland.domain.common.entity.Language; +import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.market.entity.Market; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.member.entity.Provider; +import jakarta.persistence.EntityManager; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class MarketServiceTest { + + @Autowired + EntityManager em; + @Autowired + MarketService marketService; + @Autowired + FavoriteRepository favoriteRepository; + + Language language; + Member member1, member2; + Market market; + Category category; + + @BeforeEach + void init() { + ImageFile imageFile1 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile1); + + ImageFile imageFile2 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile2); + + language = Language.builder() + .locale(Locale.KOREAN) + .dateFormat("yy-mm-dd") + .build(); + em.persist(language); + + member1 = Member.builder() + .email("test@naver.com") + .provider(Provider.KAKAO) + .providerId(123456789L) + .nickname("nickname1") + .language(language) + .profileImageFile(imageFile1) + .build(); + em.persist(member1); + + member2 = Member.builder() + .email("test2@naver.com") + .provider(Provider.KAKAO) + .providerId(1234567890L) + .nickname("nickname2") + .language(language) + .profileImageFile(imageFile2) + .build(); + em.persist(member2); + + market = Market.builder() + .imageFile(imageFile1) + .build(); + em.persist(market); + + category = Category.builder() + .content(CategoryContent.MARKET) + .build(); + em.persist(category); + } + + @Test + void toggleLikeStatusTest() { + /** + * WHEN + * + * member1 : toggleLikeStatus 2번 적용 + * member2 : toggleLikeStatus 1번 적용 + */ + marketService.toggleLikeStatus(member1, market.getId()); + marketService.toggleLikeStatus(member1, market.getId()); + + marketService.toggleLikeStatus(member2, market.getId()); + + Optional favoriteOptional1 = + favoriteRepository.findByMemberAndCategoryAndPostId(member1, category, market.getId()); + Optional favoriteOptional2 = + favoriteRepository.findByMemberAndCategoryAndPostId(member2, category, market.getId()); + + /** + * THEN + * + * member1 = 좋아요 X, member2 = 좋아요 + */ + assertThat(favoriteOptional1.isPresent()).isFalse(); + assertThat(favoriteOptional2.isPresent()).isTrue(); + } +} \ No newline at end of file From 02e00ad5f533b99f258f7ce5f7a8a00e60be1226 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:26:56 +0900 Subject: [PATCH 10/30] =?UTF-8?q?[#54]=20feat:=20nana=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/nana/controller/NanaController.java | 15 ++++++++++++++- .../nanaland/domain/nana/service/NanaService.java | 10 ++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java b/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java index 48abc2db..2c8fb7d8 100644 --- a/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java +++ b/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java @@ -1,5 +1,7 @@ package com.jeju.nanaland.domain.nana.controller; +import static com.jeju.nanaland.global.exception.SuccessCode.POST_LIKE_TOGGLE_SUCCESS; + import com.jeju.nanaland.domain.common.entity.Locale; import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.nana.dto.NanaResponse; @@ -17,6 +19,7 @@ import lombok.RequiredArgsConstructor; 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; import org.springframework.web.bind.annotation.RestController; @@ -69,5 +72,15 @@ public BaseResponse nanaDetail(@PathVariable(name = "id") Long id nanaService.getNanaDetail(id)); } - + @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) + }) + @PostMapping("/like/{id}") + public BaseResponse toggleLikeStatus(@AuthMember Member member, @PathVariable Long id) { + String result = nanaService.toggleLikeStatus(member, id); + return BaseResponse.success(POST_LIKE_TOGGLE_SUCCESS, result); + } } diff --git a/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java b/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java index f3af0801..858274ff 100644 --- a/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java +++ b/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java @@ -1,6 +1,9 @@ package com.jeju.nanaland.domain.nana.service; +import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.nana.dto.NanaResponse; import com.jeju.nanaland.domain.nana.dto.NanaResponse.NanaThumbnail; import com.jeju.nanaland.domain.nana.dto.NanaResponse.NanaThumbnailDto; @@ -17,6 +20,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -25,6 +29,7 @@ public class NanaService { private final NanaRepository nanaRepository; private final NanaTitleRepository nanaTitleRepository; private final NanaContentRepository nanaContentRepository; + private final FavoriteService favoriteService; //메인페이지에 보여지는 4개의 nana public List getMainNanaThumbnails(Locale locale) { @@ -80,4 +85,9 @@ public NanaResponse.NanaDetailDto getNanaDetail(Long id) { .build(); } + + @Transactional + public String toggleLikeStatus(Member member, Long postId) { + return favoriteService.toggleLikeStatus(member, CategoryContent.NANA, postId); + } } From bb9378ab2a67ee0e6e47c0b6a8fa28ce68e1c97a Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:31:17 +0900 Subject: [PATCH 11/30] [#54] feat: nana like test --- .../domain/nana/service/NanaServiceTest.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java diff --git a/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java b/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java new file mode 100644 index 00000000..ff428b47 --- /dev/null +++ b/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java @@ -0,0 +1,116 @@ +package com.jeju.nanaland.domain.nana.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.entity.ImageFile; +import com.jeju.nanaland.domain.common.entity.Language; +import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.member.entity.Provider; +import com.jeju.nanaland.domain.nana.entity.Nana; +import jakarta.persistence.EntityManager; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class NanaServiceTest { + + @Autowired + EntityManager em; + @Autowired + NanaService nanaService; + @Autowired + FavoriteRepository favoriteRepository; + + Language language; + Member member1, member2; + Nana nana; + Category category; + + @BeforeEach + void init() { + ImageFile imageFile1 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile1); + + ImageFile imageFile2 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile2); + + language = Language.builder() + .locale(Locale.KOREAN) + .dateFormat("yy-mm-dd") + .build(); + em.persist(language); + + member1 = Member.builder() + .email("test@naver.com") + .provider(Provider.KAKAO) + .providerId(123456789L) + .nickname("nickname1") + .language(language) + .profileImageFile(imageFile1) + .build(); + em.persist(member1); + + member2 = Member.builder() + .email("test2@naver.com") + .provider(Provider.KAKAO) + .providerId(1234567890L) + .nickname("nickname2") + .language(language) + .profileImageFile(imageFile2) + .build(); + em.persist(member2); + + nana = Nana.builder() + .version("version1") + .build(); + em.persist(nana); + + category = Category.builder() + .content(CategoryContent.NANA) + .build(); + em.persist(category); + } + + @Test + void toggleLikeStatusTest() { + /** + * WHEN + * + * member1 : toggleLikeStatus 2번 적용 + * member2 : toggleLikeStatus 1번 적용 + */ + nanaService.toggleLikeStatus(member1, nana.getId()); + nanaService.toggleLikeStatus(member1, nana.getId()); + + nanaService.toggleLikeStatus(member2, nana.getId()); + + Optional favoriteOptional1 = + favoriteRepository.findByMemberAndCategoryAndPostId(member1, category, nana.getId()); + Optional favoriteOptional2 = + favoriteRepository.findByMemberAndCategoryAndPostId(member2, category, nana.getId()); + + /** + * THEN + * + * member1 = 좋아요 X, member2 = 좋아요 + */ + assertThat(favoriteOptional1.isPresent()).isFalse(); + assertThat(favoriteOptional2.isPresent()).isTrue(); + } +} \ No newline at end of file From 7e8d7d7b709fd1c077509665b58b4cd5ab9ceb68 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:33:25 +0900 Subject: [PATCH 12/30] =?UTF-8?q?[#54]=20feat:=20nature=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nature/controller/NatureController.java | 42 +++++++++++++++++++ .../domain/nature/service/NatureService.java | 22 ++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java create mode 100644 src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java diff --git a/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java b/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java new file mode 100644 index 00000000..8a2c3020 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java @@ -0,0 +1,42 @@ +package com.jeju.nanaland.domain.nature.controller; + + +import static com.jeju.nanaland.global.exception.SuccessCode.POST_LIKE_TOGGLE_SUCCESS; + +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.nature.service.NatureService; +import com.jeju.nanaland.global.BaseResponse; +import com.jeju.nanaland.global.jwt.AuthMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/nature") +@Slf4j +@Tag(name = "7대자연(Nature)", description = "7대자연(Nature) API입니다.") +public class NatureController { + + private final NatureService natureService; + + @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) + }) + @PostMapping("/like/{id}") + public BaseResponse toggleLikeStatus(@AuthMember Member member, @PathVariable Long id) { + String result = natureService.toggleLikeStatus(member, id); + return BaseResponse.success(POST_LIKE_TOGGLE_SUCCESS, result); + } +} diff --git a/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java b/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java new file mode 100644 index 00000000..1f81da15 --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java @@ -0,0 +1,22 @@ +package com.jeju.nanaland.domain.nature.service; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.member.entity.Member; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Slf4j +public class NatureService { + + private final FavoriteService favoriteService; + + @Transactional + public String toggleLikeStatus(Member member, Long postId) { + return favoriteService.toggleLikeStatus(member, CategoryContent.NATURE, postId); + } +} From 7b551b55d71656e4ee97f808ec14257d68f0d146 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:35:51 +0900 Subject: [PATCH 13/30] [#54] feat: nature like test --- .../nature/service/NatureServiceTest.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java diff --git a/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java b/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java new file mode 100644 index 00000000..bb5a33dd --- /dev/null +++ b/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java @@ -0,0 +1,116 @@ +package com.jeju.nanaland.domain.nature.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.entity.ImageFile; +import com.jeju.nanaland.domain.common.entity.Language; +import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.member.entity.Provider; +import com.jeju.nanaland.domain.nature.entity.Nature; +import jakarta.persistence.EntityManager; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class NatureServiceTest { + + @Autowired + EntityManager em; + @Autowired + NatureService natureService; + @Autowired + FavoriteRepository favoriteRepository; + + Language language; + Member member1, member2; + Nature nature; + Category category; + + @BeforeEach + void init() { + ImageFile imageFile1 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile1); + + ImageFile imageFile2 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile2); + + language = Language.builder() + .locale(Locale.KOREAN) + .dateFormat("yy-mm-dd") + .build(); + em.persist(language); + + member1 = Member.builder() + .email("test@naver.com") + .provider(Provider.KAKAO) + .providerId(123456789L) + .nickname("nickname1") + .language(language) + .profileImageFile(imageFile1) + .build(); + em.persist(member1); + + member2 = Member.builder() + .email("test2@naver.com") + .provider(Provider.KAKAO) + .providerId(1234567890L) + .nickname("nickname2") + .language(language) + .profileImageFile(imageFile2) + .build(); + em.persist(member2); + + nature = Nature.builder() + .imageFile(imageFile1) + .build(); + em.persist(nature); + + category = Category.builder() + .content(CategoryContent.NATURE) + .build(); + em.persist(category); + } + + @Test + void toggleLikeStatusTest() { + /** + * WHEN + * + * member1 : toggleLikeStatus 2번 적용 + * member2 : toggleLikeStatus 1번 적용 + */ + natureService.toggleLikeStatus(member1, nature.getId()); + natureService.toggleLikeStatus(member1, nature.getId()); + + natureService.toggleLikeStatus(member2, nature.getId()); + + Optional favoriteOptional1 = + favoriteRepository.findByMemberAndCategoryAndPostId(member1, category, nature.getId()); + Optional favoriteOptional2 = + favoriteRepository.findByMemberAndCategoryAndPostId(member2, category, nature.getId()); + + /** + * THEN + * + * member1 = 좋아요 X, member2 = 좋아요 + */ + assertThat(favoriteOptional1.isPresent()).isFalse(); + assertThat(favoriteOptional2.isPresent()).isTrue(); + } +} \ No newline at end of file From 1460c3bd86a3645dc66eca3e80b92f19d24055a0 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:48:19 +0900 Subject: [PATCH 14/30] =?UTF-8?q?[#54]=20feat:=20experience=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/experience/service/ExperienceService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java b/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java index a7f818ed..fe8d3091 100644 --- a/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java +++ b/src/main/java/com/jeju/nanaland/domain/experience/service/ExperienceService.java @@ -1,8 +1,10 @@ package com.jeju.nanaland.domain.experience.service; import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.experience.repository.ExperienceRepository; import com.jeju.nanaland.domain.favorite.service.FavoriteService; import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -13,10 +15,14 @@ @Slf4j public class ExperienceService { + private final ExperienceRepository experienceRepository; private final FavoriteService favoriteService; @Transactional public String toggleLikeStatus(Member member, Long postId) { + experienceRepository.findById(postId) + .orElseThrow(() -> new BadRequestException("해당 id의 이색체험 게시물이 존재하지 않습니다.")); + return favoriteService.toggleLikeStatus(member, CategoryContent.EXPERIENCE, postId); } } From b7953c8f52ede883d7765d8c457167e0c5c98ca6 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:49:09 +0900 Subject: [PATCH 15/30] =?UTF-8?q?[#54]=20feat:=20festival=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanaland/domain/festival/service/FestivalService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java b/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java index 01520790..4cbea582 100644 --- a/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java +++ b/src/main/java/com/jeju/nanaland/domain/festival/service/FestivalService.java @@ -2,7 +2,9 @@ import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.festival.repository.FestivalRepository; import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -13,10 +15,14 @@ @Slf4j public class FestivalService { + private final FestivalRepository festivalRepository; private final FavoriteService favoriteService; @Transactional public String toggleLikeStatus(Member member, Long postId) { + festivalRepository.findById(postId) + .orElseThrow(() -> new BadRequestException("해당 id의 축제 게시물이 존재하지 않습니다.")); + return favoriteService.toggleLikeStatus(member, CategoryContent.FESTIVAL, postId); } } From 0aa9958e5da67150b4565d93e6d5bcf511070006 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:50:01 +0900 Subject: [PATCH 16/30] =?UTF-8?q?[#54]=20feat:=20market=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeju/nanaland/domain/market/service/MarketService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java b/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java index 8d1dd6da..0ced0781 100644 --- a/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java +++ b/src/main/java/com/jeju/nanaland/domain/market/service/MarketService.java @@ -2,7 +2,9 @@ import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.market.repository.MarketRepository; import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -13,10 +15,14 @@ @Slf4j public class MarketService { + private final MarketRepository marketRepository; private final FavoriteService favoriteService; @Transactional public String toggleLikeStatus(Member member, Long postId) { + marketRepository.findById(postId) + .orElseThrow(() -> new BadRequestException("해당 id의 전통시장 게시물이 존재하지 않습니다.")); + return favoriteService.toggleLikeStatus(member, CategoryContent.MARKET, postId); } } From d52295f09f11dedea1f46d142d58b6676d4d340c Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:50:28 +0900 Subject: [PATCH 17/30] =?UTF-8?q?[#54]=20feat:=20nana=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jeju/nanaland/domain/nana/service/NanaService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java b/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java index 858274ff..5664f52b 100644 --- a/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java +++ b/src/main/java/com/jeju/nanaland/domain/nana/service/NanaService.java @@ -88,6 +88,9 @@ public NanaResponse.NanaDetailDto getNanaDetail(Long id) { @Transactional public String toggleLikeStatus(Member member, Long postId) { + nanaRepository.findById(postId) + .orElseThrow(() -> new BadRequestException("해당 id의 나나스픽 게시물이 존재하지 않습니다.")); + return favoriteService.toggleLikeStatus(member, CategoryContent.NANA, postId); } } From 7c6fbd7ac3132248a24ab6b34f9a74a73e902ae6 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:50:56 +0900 Subject: [PATCH 18/30] =?UTF-8?q?[#54]=20feat:=20nature=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeju/nanaland/domain/nature/service/NatureService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java b/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java index 1f81da15..d254369e 100644 --- a/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java +++ b/src/main/java/com/jeju/nanaland/domain/nature/service/NatureService.java @@ -3,6 +3,8 @@ import com.jeju.nanaland.domain.common.data.CategoryContent; import com.jeju.nanaland.domain.favorite.service.FavoriteService; import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.nature.repository.NatureRepository; +import com.jeju.nanaland.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -13,10 +15,14 @@ @Slf4j public class NatureService { + private final NatureRepository natureRepository; private final FavoriteService favoriteService; @Transactional public String toggleLikeStatus(Member member, Long postId) { + natureRepository.findById(postId) + .orElseThrow(() -> new BadRequestException("해당 id의 7대자연 게시물이 존재하지 않습니다.")); + return favoriteService.toggleLikeStatus(member, CategoryContent.NATURE, postId); } } From a85434f73d47338c46c60ffdd8cc50706f4e449b Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:53:09 +0900 Subject: [PATCH 19/30] =?UTF-8?q?[#54]=20feat:=20nature=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanaland/domain/nature/controller/NatureController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java b/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java index 8a2c3020..e6b7549d 100644 --- a/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java +++ b/src/main/java/com/jeju/nanaland/domain/nature/controller/NatureController.java @@ -31,7 +31,7 @@ public class NatureController { @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), - @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우 또는 해당 id의 게시물이 없는 경우", content = @Content), @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) }) @PostMapping("/like/{id}") From 801e9a6f366f4c57f589224e4eb03fda7724cee3 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:53:27 +0900 Subject: [PATCH 20/30] =?UTF-8?q?[#54]=20feat:=20nana=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeju/nanaland/domain/nana/controller/NanaController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java b/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java index 2c8fb7d8..cd66b902 100644 --- a/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java +++ b/src/main/java/com/jeju/nanaland/domain/nana/controller/NanaController.java @@ -75,7 +75,7 @@ public BaseResponse nanaDetail(@PathVariable(name = "id") Long id @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), - @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우 또는 해당 id의 게시물이 없는 경우", content = @Content), @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) }) @PostMapping("/like/{id}") From f2f12be7815e2d059ec017928e957bf6611ca5cf Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:53:42 +0900 Subject: [PATCH 21/30] =?UTF-8?q?[#54]=20feat:=20market=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanaland/domain/market/controller/MarketController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java b/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java index e78b4c40..64eca7a4 100644 --- a/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java +++ b/src/main/java/com/jeju/nanaland/domain/market/controller/MarketController.java @@ -30,7 +30,7 @@ public class MarketController { @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), - @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우 또는 해당 id의 게시물이 없는 경우", content = @Content), @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) }) @PostMapping("/like/{id}") From 6393ca5aaf6358aaea281801cbe28fcb9dbbf029 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:53:53 +0900 Subject: [PATCH 22/30] =?UTF-8?q?[#54]=20feat:=20festival=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanaland/domain/festival/controller/FestivalController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java index 1d964d9e..2cddb167 100644 --- a/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java +++ b/src/main/java/com/jeju/nanaland/domain/festival/controller/FestivalController.java @@ -30,7 +30,7 @@ public class FestivalController { @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), - @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우 또는 해당 id의 게시물이 없는 경우", content = @Content), @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) }) @PostMapping("/like/{id}") From 81c842d04d13df66d3e933559cb8ccebb31917fe Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 13:54:04 +0900 Subject: [PATCH 23/30] =?UTF-8?q?[#54]=20feat:=20experience=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/experience/controller/ExperienceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java b/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java index 87674414..01639493 100644 --- a/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java +++ b/src/main/java/com/jeju/nanaland/domain/experience/controller/ExperienceController.java @@ -30,7 +30,7 @@ public class ExperienceController { @Operation(summary = "좋아요 토글", description = "좋아요 토글 기능 (좋아요 상태 -> 좋아요 취소 상태, 좋아요 취소 상태 -> 좋아요 상태)") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), - @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우", content = @Content), + @ApiResponse(responseCode = "400", description = "필요한 입력이 없는 경우 또는 해당 id의 게시물이 없는 경우", content = @Content), @ApiResponse(responseCode = "500", description = "서버측 에러", content = @Content) }) @PostMapping("/like/{id}") From 5e20cf20a74f873d6dcc497564acc7a36a58ad53 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 14:04:24 +0900 Subject: [PATCH 24/30] [#54] feat: nature like test --- .../nature/service/NatureServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java b/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java index bb5a33dd..c8de4672 100644 --- a/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/nature/service/NatureServiceTest.java @@ -12,8 +12,10 @@ import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.member.entity.Provider; import com.jeju.nanaland.domain.nature.entity.Nature; +import com.jeju.nanaland.global.exception.BadRequestException; import jakarta.persistence.EntityManager; import java.util.Optional; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -113,4 +115,23 @@ void toggleLikeStatusTest() { assertThat(favoriteOptional1.isPresent()).isFalse(); assertThat(favoriteOptional2.isPresent()).isTrue(); } + + @Test + void toggleLikeStatusFailedWithNoSuchPostIdTest() { + /** + * GIVEN + * + * 존재하지 않는 postId + */ + Long postId = -1L; + + /** + * WHEN + * THEN + * + * toggleLikeStatus 요청 시 BadRequestException 발생 + */ + Assertions.assertThatThrownBy(() -> natureService.toggleLikeStatus(member1, postId)) + .isInstanceOf(BadRequestException.class); + } } \ No newline at end of file From 97bae6355a66de83a00c5c7d3ff2fb8fb90e83f8 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 14:04:51 +0900 Subject: [PATCH 25/30] [#54] feat: nana like test --- .../domain/nana/service/NanaServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java b/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java index ff428b47..0f0620c4 100644 --- a/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/nana/service/NanaServiceTest.java @@ -12,8 +12,10 @@ import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.member.entity.Provider; import com.jeju.nanaland.domain.nana.entity.Nana; +import com.jeju.nanaland.global.exception.BadRequestException; import jakarta.persistence.EntityManager; import java.util.Optional; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -113,4 +115,23 @@ void toggleLikeStatusTest() { assertThat(favoriteOptional1.isPresent()).isFalse(); assertThat(favoriteOptional2.isPresent()).isTrue(); } + + @Test + void toggleLikeStatusFailedWithNoSuchPostIdTest() { + /** + * GIVEN + * + * 존재하지 않는 postId + */ + Long postId = -1L; + + /** + * WHEN + * THEN + * + * toggleLikeStatus 요청 시 BadRequestException 발생 + */ + Assertions.assertThatThrownBy(() -> nanaService.toggleLikeStatus(member1, postId)) + .isInstanceOf(BadRequestException.class); + } } \ No newline at end of file From 1708d49072d3a3ae225da0ab4dda2e45f8f31de9 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 14:05:11 +0900 Subject: [PATCH 26/30] [#54] feat: festival like test --- .../festival/service/FestivalServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java b/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java index 5b24d9a0..10277eea 100644 --- a/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/festival/service/FestivalServiceTest.java @@ -12,8 +12,10 @@ import com.jeju.nanaland.domain.festival.entity.Festival; import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.member.entity.Provider; +import com.jeju.nanaland.global.exception.BadRequestException; import jakarta.persistence.EntityManager; import java.util.Optional; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -113,4 +115,23 @@ void toggleLikeStatusTest() { assertThat(favoriteOptional1.isPresent()).isFalse(); assertThat(favoriteOptional2.isPresent()).isTrue(); } + + @Test + void toggleLikeStatusFailedWithNoSuchPostIdTest() { + /** + * GIVEN + * + * 존재하지 않는 postId + */ + Long postId = -1L; + + /** + * WHEN + * THEN + * + * toggleLikeStatus 요청 시 BadRequestException 발생 + */ + Assertions.assertThatThrownBy(() -> festivalService.toggleLikeStatus(member1, postId)) + .isInstanceOf(BadRequestException.class); + } } \ No newline at end of file From 9cdd8c4f04b098acb9ac7c113a02953a949a5727 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 14:05:33 +0900 Subject: [PATCH 27/30] [#54] feat: experience like test --- .../service/ExperienceServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java index 72309565..50f589c7 100644 --- a/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/experience/service/ExperienceServiceTest.java @@ -12,8 +12,10 @@ import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.member.entity.Provider; +import com.jeju.nanaland.global.exception.BadRequestException; import jakarta.persistence.EntityManager; import java.util.Optional; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -113,4 +115,23 @@ void toggleLikeStatusTest() { assertThat(favoriteOptional1.isPresent()).isFalse(); assertThat(favoriteOptional2.isPresent()).isTrue(); } + + @Test + void toggleLikeStatusFailedWithNoSuchPostIdTest() { + /** + * GIVEN + * + * 존재하지 않는 postId + */ + Long postId = -1L; + + /** + * WHEN + * THEN + * + * toggleLikeStatus 요청 시 BadRequestException 발생 + */ + Assertions.assertThatThrownBy(() -> experienceService.toggleLikeStatus(member1, postId)) + .isInstanceOf(BadRequestException.class); + } } \ No newline at end of file From d293321e0a3f12bd00de139c86dde75b88ec9e47 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 14:05:52 +0900 Subject: [PATCH 28/30] [#54] feat: market like test --- .../market/service/MarketServiceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java b/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java index fb13c991..2ced1a34 100644 --- a/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java +++ b/src/test/java/com/jeju/nanaland/domain/market/service/MarketServiceTest.java @@ -12,8 +12,10 @@ import com.jeju.nanaland.domain.market.entity.Market; import com.jeju.nanaland.domain.member.entity.Member; import com.jeju.nanaland.domain.member.entity.Provider; +import com.jeju.nanaland.global.exception.BadRequestException; import jakarta.persistence.EntityManager; import java.util.Optional; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -113,4 +115,23 @@ void toggleLikeStatusTest() { assertThat(favoriteOptional1.isPresent()).isFalse(); assertThat(favoriteOptional2.isPresent()).isTrue(); } + + @Test + void toggleLikeStatusFailedWithNoSuchPostIdTest() { + /** + * GIVEN + * + * 존재하지 않는 postId + */ + Long postId = -1L; + + /** + * WHEN + * THEN + * + * toggleLikeStatus 요청 시 BadRequestException 발생 + */ + Assertions.assertThatThrownBy(() -> marketService.toggleLikeStatus(member1, postId)) + .isInstanceOf(BadRequestException.class); + } } \ No newline at end of file From 540d525ae152b01b2c4f538bf176136649fa8e85 Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 15:15:46 +0900 Subject: [PATCH 29/30] =?UTF-8?q?[#55]=20feat:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=EC=97=90=20=EC=A2=8B=EC=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/FavoriteRepository.java | 8 +++++ .../domain/search/dto/SearchResponse.java | 7 ++-- .../domain/search/service/SearchService.java | 34 ++++++++++--------- 3 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java diff --git a/src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java b/src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java new file mode 100644 index 00000000..b5e6c2db --- /dev/null +++ b/src/main/java/com/jeju/nanaland/domain/favorite/repository/FavoriteRepository.java @@ -0,0 +1,8 @@ +package com.jeju.nanaland.domain.favorite.repository; + +import com.jeju.nanaland.domain.favorite.entity.Favorite; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FavoriteRepository extends JpaRepository { + +} diff --git a/src/main/java/com/jeju/nanaland/domain/search/dto/SearchResponse.java b/src/main/java/com/jeju/nanaland/domain/search/dto/SearchResponse.java index c5fa197c..fdff6dc3 100644 --- a/src/main/java/com/jeju/nanaland/domain/search/dto/SearchResponse.java +++ b/src/main/java/com/jeju/nanaland/domain/search/dto/SearchResponse.java @@ -34,8 +34,8 @@ public static class StoryDto { @Builder public static class ResultDto { - @Schema(description = "총 조회 개수") - private Long count; + @Schema(description = "총 항목 개수") + private Long totalElements; @Schema(description = "결과 데이터") private List data; @@ -53,5 +53,8 @@ public static class ThumbnailDto { @Schema(description = "제목") private String title; + + @Schema(description = "좋아요 여부") + private boolean isFavorite; } } diff --git a/src/main/java/com/jeju/nanaland/domain/search/service/SearchService.java b/src/main/java/com/jeju/nanaland/domain/search/service/SearchService.java index 2da804ed..03df9149 100644 --- a/src/main/java/com/jeju/nanaland/domain/search/service/SearchService.java +++ b/src/main/java/com/jeju/nanaland/domain/search/service/SearchService.java @@ -3,6 +3,7 @@ import com.jeju.nanaland.domain.common.entity.Locale; import com.jeju.nanaland.domain.experience.dto.ExperienceCompositeDto; import com.jeju.nanaland.domain.experience.repository.ExperienceRepository; +import com.jeju.nanaland.domain.favorite.repository.FavoriteRepository; import com.jeju.nanaland.domain.festival.dto.FestivalCompositeDto; import com.jeju.nanaland.domain.festival.repository.FestivalRepository; import com.jeju.nanaland.domain.market.dto.MarketCompositeDto; @@ -34,6 +35,7 @@ public class SearchService { private final ExperienceRepository experienceRepository; private final MarketRepository marketRepository; private final FestivalRepository festivalRepository; + private final FavoriteRepository favoriteRepository; private final RedisTemplate redisTemplate; public SearchResponse.CategoryDto getCategorySearchResultDto(String keyword, Locale locale) { @@ -55,11 +57,11 @@ public SearchResponse.ResultDto getNatureSearchResultDto(String keyword, Locale int page, int size) { Pageable pageable = PageRequest.of(page, size); - Page ResultDto = natureRepository.searchCompositeDtoByTitle(keyword, locale, - pageable); + Page resultPage = natureRepository.searchCompositeDtoByTitle( + keyword, locale, pageable); List thumbnails = new ArrayList<>(); - for (NatureCompositeDto dto : ResultDto) { + for (NatureCompositeDto dto : resultPage) { thumbnails.add( ThumbnailDto.builder() .id(dto.getId()) @@ -69,7 +71,7 @@ public SearchResponse.ResultDto getNatureSearchResultDto(String keyword, Locale } return SearchResponse.ResultDto.builder() - .count(ResultDto.getTotalElements()) + .totalElements(resultPage.getTotalElements()) .data(thumbnails) .build(); } @@ -78,11 +80,11 @@ public SearchResponse.ResultDto getFestivalSearchResultDto(String keyword, Local int page, int size) { Pageable pageable = PageRequest.of(page, size); - Page ResultDto = festivalRepository.searchCompositeDtoByTitle(keyword, - locale, pageable); + Page resultPage = festivalRepository.searchCompositeDtoByTitle( + keyword, locale, pageable); List thumbnails = new ArrayList<>(); - for (FestivalCompositeDto dto : ResultDto) { + for (FestivalCompositeDto dto : resultPage) { thumbnails.add( ThumbnailDto.builder() .id(dto.getId()) @@ -92,7 +94,7 @@ public SearchResponse.ResultDto getFestivalSearchResultDto(String keyword, Local } return SearchResponse.ResultDto.builder() - .count(ResultDto.getTotalElements()) + .totalElements(resultPage.getTotalElements()) .data(thumbnails) .build(); } @@ -101,11 +103,11 @@ public SearchResponse.ResultDto getExperienceSearchResultDto(String keyword, Loc int page, int size) { Pageable pageable = PageRequest.of(page, size); - Page ResultDto = experienceRepository.searchCompositeDtoByTitle(keyword, - locale, pageable); + Page resultPage = experienceRepository.searchCompositeDtoByTitle( + keyword, locale, pageable); List thumbnails = new ArrayList<>(); - for (ExperienceCompositeDto dto : ResultDto) { + for (ExperienceCompositeDto dto : resultPage) { thumbnails.add( ThumbnailDto.builder() .id(dto.getId()) @@ -115,7 +117,7 @@ public SearchResponse.ResultDto getExperienceSearchResultDto(String keyword, Loc } return SearchResponse.ResultDto.builder() - .count(ResultDto.getTotalElements()) + .totalElements(resultPage.getTotalElements()) .data(thumbnails) .build(); } @@ -124,11 +126,11 @@ public SearchResponse.ResultDto getMarketSearchResultDto(String keyword, Locale int page, int size) { Pageable pageable = PageRequest.of(page, size); - Page ResultDto = marketRepository.searchCompositeDtoByTitle(keyword, locale, - pageable); + Page resultPage = marketRepository.searchCompositeDtoByTitle( + keyword, locale, pageable); List thumbnails = new ArrayList<>(); - for (MarketCompositeDto dto : ResultDto) { + for (MarketCompositeDto dto : resultPage) { thumbnails.add( ThumbnailDto.builder() .id(dto.getId()) @@ -138,7 +140,7 @@ public SearchResponse.ResultDto getMarketSearchResultDto(String keyword, Locale } return SearchResponse.ResultDto.builder() - .count(ResultDto.getTotalElements()) + .totalElements(resultPage.getTotalElements()) .data(thumbnails) .build(); } From 271b865181297baa132ebc55d35c5f1c51d5f1bc Mon Sep 17 00:00:00 2001 From: seokhee Date: Fri, 19 Apr 2024 16:07:28 +0900 Subject: [PATCH 30/30] [#55] feat: search service test --- .../search/service/SearchServiceTest.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/test/java/com/jeju/nanaland/domain/search/service/SearchServiceTest.java diff --git a/src/test/java/com/jeju/nanaland/domain/search/service/SearchServiceTest.java b/src/test/java/com/jeju/nanaland/domain/search/service/SearchServiceTest.java new file mode 100644 index 00000000..aeeb32e6 --- /dev/null +++ b/src/test/java/com/jeju/nanaland/domain/search/service/SearchServiceTest.java @@ -0,0 +1,124 @@ +package com.jeju.nanaland.domain.search.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.jeju.nanaland.domain.common.data.CategoryContent; +import com.jeju.nanaland.domain.common.entity.Category; +import com.jeju.nanaland.domain.common.entity.ImageFile; +import com.jeju.nanaland.domain.common.entity.Language; +import com.jeju.nanaland.domain.common.entity.Locale; +import com.jeju.nanaland.domain.favorite.service.FavoriteService; +import com.jeju.nanaland.domain.market.entity.Market; +import com.jeju.nanaland.domain.market.entity.MarketTrans; +import com.jeju.nanaland.domain.member.entity.Member; +import com.jeju.nanaland.domain.member.entity.Provider; +import com.jeju.nanaland.domain.search.dto.SearchResponse.ResultDto; +import jakarta.persistence.EntityManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +@SpringBootTest +@Transactional +class SearchServiceTest { + + @Autowired + EntityManager em; + @Autowired + SearchService searchService; + @Autowired + FavoriteService favoriteService; + + Language language; + Member member; + ImageFile imageFile1, imageFile2; + Category category; + + @BeforeEach + void init() { + imageFile1 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile1); + imageFile2 = ImageFile.builder() + .originUrl("origin") + .thumbnailUrl("thumbnail") + .build(); + em.persist(imageFile2); + + language = Language.builder() + .locale(Locale.KOREAN) + .dateFormat("yy-mm-dd") + .build(); + em.persist(language); + + member = Member.builder() + .email("test@naver.com") + .provider(Provider.KAKAO) + .providerId(123456789L) + .nickname("nickname1") + .language(language) + .profileImageFile(imageFile1) + .build(); + em.persist(member); + + category = Category.builder() + .content(CategoryContent.MARKET) + .build(); + em.persist(category); + } + + @Test + void marketSearchTest() { + /** + * GIVEN + * + * market1 -> title1 + * market2 -> title2 + */ + Market market1 = Market.builder() + .imageFile(imageFile1) + .build(); + em.persist(market1); + Market market2 = Market.builder() + .imageFile(imageFile2) + .build(); + em.persist(market2); + + MarketTrans marketTrans1 = MarketTrans.builder() + .market(market1) + .language(language) + .title("title1") + .build(); + em.persist(marketTrans1); + MarketTrans marketTrans2 = MarketTrans.builder() + .market(market2) + .language(language) + .title("title2") + .build(); + em.persist(marketTrans2); + + /** + * WHEN + * + * result1 : keyword = title + * result2 : keyword = title1 + */ + ResultDto result1 = + searchService.getMarketSearchResultDto(member, "title", Locale.KOREAN, 0, 4); + ResultDto result2 = + searchService.getMarketSearchResultDto(member, "title1", Locale.KOREAN, 0, 4); + + /** + * THEN + * + * result1의 totalElements = 2 + * result2의 totalElements = 1 + */ + assertThat(result1.getData().size()).isEqualTo(2); + assertThat(result2.getData().size()).isEqualTo(1); + } +} \ No newline at end of file