From 09b8c3b4fb77c46c88c117d88e24c732eefc8ed0 Mon Sep 17 00:00:00 2001 From: Daeun <74234333+punchdrunkard@users.noreply.github.com> Date: Tue, 8 Oct 2024 06:07:35 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EA=B0=80=20=EC=97=AC=EB=9F=AC=20=EA=B0=9C=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=8A=A4=ED=8B=B0=EB=B2=8C=EC=9D=B4=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EB=90=98=EB=8A=94=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#169)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/FestivalCustomRepository.java | 2 +- .../FestivalCustomRepositoryImpl.java | 34 +----- .../festival/service/FestivalService.java | 12 ++ .../user/controller/UserController.java | 12 +- .../fiesta/user/service/UserService.java | 13 +- .../repository/FestivalRepositoryTest.java | 61 ---------- .../festival/service/FestivalServiceTest.java | 111 +++++++++++++++++- .../fiesta/user/service/UserServiceTest.java | 29 ----- 8 files changed, 137 insertions(+), 137 deletions(-) diff --git a/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepository.java b/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepository.java index 7085dfde..f6c258b3 100644 --- a/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepository.java +++ b/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepository.java @@ -41,5 +41,5 @@ Page findFestivalsAndSidoWithinDateRange(LocalDate startDate, Map findThumbnailImageByFestivalId(List festivalIds); - Page findBookmarkedFestivals(Long userId, Pageable pageable); + Page findBookmarkedFestivals(Long userId, Pageable pageable); } diff --git a/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepositoryImpl.java b/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepositoryImpl.java index 7b529839..14134a48 100644 --- a/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepositoryImpl.java +++ b/src/main/java/com/odiga/fiesta/festival/repository/FestivalCustomRepositoryImpl.java @@ -306,41 +306,15 @@ public Map findThumbnailImageByFestivalId(List festivalIds) } @Override - public Page findBookmarkedFestivals(Long userId, Pageable pageable) { - List festivals = queryFactory.select( - Projections.fields(FestivalInfoWithBookmark.class, - festival.id.as("festivalId"), - festival.name, - sido.name.as("sido"), - festival.sigungu, - min(festivalImage.imageUrl).as("thumbnailImage"), - festival.startDate, - festival.endDate, + public Page findBookmarkedFestivals(Long userId, Pageable pageable) { - new CaseBuilder() - .when(festivalBookmarkUserIdEq(userId)) - .then(true) - .otherwise(false).as("isBookmarked") - ) - ).from(festival) + List festivals = selectFestivalsWithBookmarkAndSido(pageable, userId) .where(festivalBookmarkUserIdEq(userId)) - .leftJoin(festivalBookmarkForIsBookmarked) - .on(festivalBookmarkForIsBookmarked.festivalId.eq(festival.id), - festivalBookmarkUserIdEq(userId)) - .leftJoin(sido) - .on(sidoIdFestivalSidoIdEq()) - .leftJoin(festivalImage) - .on(festival.id.eq(festivalImage.festivalId)) .orderBy(festivalBookmarkForIsBookmarked.createdAt.desc()) - .offset(pageable.getOffset()) - .limit(pageable.getPageSize()) .fetch(); - JPAQuery countQuery = queryFactory.select(festival.count()) - .from(festival) - .leftJoin(festivalBookmarkForIsBookmarked) - .on(festivalBookmarkForIsBookmarked.festivalId.eq(festival.id), - festivalBookmarkUserIdEq(userId)) + JPAQuery countQuery = queryFactory.select(festivalBookmarkForIsBookmarked.count()) + .from(festivalBookmarkForIsBookmarked) .where(festivalBookmarkUserIdEq(userId)); return PageableExecutionUtils.getPage(festivals, pageable, countQuery::fetchOne); diff --git a/src/main/java/com/odiga/fiesta/festival/service/FestivalService.java b/src/main/java/com/odiga/fiesta/festival/service/FestivalService.java index 03d3d164..04be7742 100644 --- a/src/main/java/com/odiga/fiesta/festival/service/FestivalService.java +++ b/src/main/java/com/odiga/fiesta/festival/service/FestivalService.java @@ -212,6 +212,18 @@ public PageResponse getTrendingFestival(String rankingKey, Long p (page.intValue() / size) + 1); } + public Page getBookmarkedFestivals(User user, Pageable pageable) { + validateUserId(user.getId()); + + Page bookmarkedFestivals = festivalRepository.findBookmarkedFestivals(user.getId(), + pageable); + + List festivals = getFestivalWithBookmarkAndSidoAndThumbnailImage( + bookmarkedFestivals); + + return new PageImpl<>(festivals, pageable, bookmarkedFestivals.getTotalElements()); + } + private List getFestivalWithBookmarkAndSidoAndThumbnailImage( Page festivalsByFilters) { // 1. 페스티벌 아이디를 가져온다. diff --git a/src/main/java/com/odiga/fiesta/user/controller/UserController.java b/src/main/java/com/odiga/fiesta/user/controller/UserController.java index ba6f4656..969010df 100644 --- a/src/main/java/com/odiga/fiesta/user/controller/UserController.java +++ b/src/main/java/com/odiga/fiesta/user/controller/UserController.java @@ -26,6 +26,7 @@ import com.odiga.fiesta.common.error.ErrorCode; import com.odiga.fiesta.common.error.exception.CustomException; import com.odiga.fiesta.festival.dto.response.FestivalInfoWithBookmark; +import com.odiga.fiesta.festival.service.FestivalService; import com.odiga.fiesta.user.domain.User; import com.odiga.fiesta.user.dto.request.ProfileCreateRequest; import com.odiga.fiesta.user.dto.request.SocialLoginRequest; @@ -56,7 +57,8 @@ public class UserController { private final UserService userService; private final AuthService authService; private final BadgeService badgeService; - + private final FestivalService festivalService; + @PostMapping("/oauth/login") @Operation(summary = "소셜 로그인", description = "소셜 로그인을 진행합니다.") public ResponseEntity> kakaoLogin(@RequestBody SocialLoginRequest request) { @@ -112,8 +114,8 @@ public ResponseEntity> reissue(@RequestHeade } @Operation( - summary = "유저가 스크랩한 페스티벌 조회", - description = "유저가 스크랩한 페스티벌을 다건 조회합니다." + summary = "유저가 북마크한 페스티벌 조회", + description = "유저가 북마크한 페스티벌을 다건 조회합니다." ) @GetMapping("/bookmarks") public ResponseEntity>> getBookmarkedFestivals( @@ -121,8 +123,8 @@ public ResponseEntity>> get @ParameterObject @Parameter(description = "Paging parameters", example = "{\"page\":0,\"size\":6,\"sort\":[\"createdAt,desc\"]}") @PageableDefault(sort = {"createdAt"}, direction = Sort.Direction.DESC, size = 6) Pageable pageable) { - Page festivals = userService.getBookmarkedFestivals(user, pageable); - return ResponseEntity.ok(BasicResponse.ok("스크랩한 페스티벌 조회 성공", PageResponse.of(festivals))); + Page festivals = festivalService.getBookmarkedFestivals(user, pageable); + return ResponseEntity.ok(BasicResponse.ok("북마크한 페스티벌 조회 성공", PageResponse.of(festivals))); } @GetMapping("/badges") diff --git a/src/main/java/com/odiga/fiesta/user/service/UserService.java b/src/main/java/com/odiga/fiesta/user/service/UserService.java index 1ff0c762..3fa3ebd4 100644 --- a/src/main/java/com/odiga/fiesta/user/service/UserService.java +++ b/src/main/java/com/odiga/fiesta/user/service/UserService.java @@ -23,8 +23,10 @@ import com.odiga.fiesta.common.error.exception.CustomException; import com.odiga.fiesta.companion.domain.Companion; import com.odiga.fiesta.companion.repository.CompanionRepository; +import com.odiga.fiesta.festival.dto.projection.FestivalWithBookmarkAndSido; import com.odiga.fiesta.festival.dto.response.FestivalInfoWithBookmark; import com.odiga.fiesta.festival.repository.FestivalRepository; +import com.odiga.fiesta.festival.service.FestivalService; import com.odiga.fiesta.mood.domain.Mood; import com.odiga.fiesta.mood.repository.MoodRepository; import com.odiga.fiesta.priority.domain.Priority; @@ -54,7 +56,9 @@ @Transactional(readOnly = true) @RequiredArgsConstructor public class UserService { + private final FestivalRepository festivalRepository; + private final FestivalService festivalService; private final UserCategoryRepository userCategoryRepository; private final UserCompanionRepository userCompanionRepository; @@ -103,15 +107,6 @@ public ProfileCreateResponse createProfile(User user, ProfileCreateRequest reque .build(); } - public Page getBookmarkedFestivals(User user, Pageable pageable) { - validateUser(user); - - Page festivals = festivalRepository.findBookmarkedFestivals(user.getId(), - pageable); - - return festivals; - } - @Transactional public UserIdResponse updateUserInfo(User user, UserInfoUpdateRequest request) { validateUser(user); diff --git a/src/test/java/com/odiga/fiesta/festival/repository/FestivalRepositoryTest.java b/src/test/java/com/odiga/fiesta/festival/repository/FestivalRepositoryTest.java index 47fcb486..8e37148d 100644 --- a/src/test/java/com/odiga/fiesta/festival/repository/FestivalRepositoryTest.java +++ b/src/test/java/com/odiga/fiesta/festival/repository/FestivalRepositoryTest.java @@ -181,67 +181,6 @@ void findThumbnailImageByFestivalId() { assertThat(thumbnailImageByFestivalId.get(festival3.getId())).isNull(); } - @DisplayName("현재 유저가 북마크 한 페스티벌들을 조회한다.") - @Test - void findBookmarkedFestivals() { - // given - User currentUser = createUser(); - em.persist(currentUser); - - User otherUser = createUser(); - em.persist(otherUser); - - Sido sido = createSido(); - em.persist(sido); - - List bookmarkedFestivals = new ArrayList<>(); - - for (int i = 0; i < 30; i++) { - Festival festival = createFestival(LocalDate.of(2024, 10, 1), LocalDate.of(2024, 10, 10), sido.getId()); - em.persist(festival); - - for (int j = 0; j < 3; j++) { - FestivalImage image = createFestivalImage(festival); - em.persist(image); - } - - FestivalBookmark bookmark = FestivalBookmark.builder() - .festivalId(festival.getId()) - .userId(currentUser.getId()) - .build(); - - em.persist(bookmark); - - bookmarkedFestivals.add(festival); - } - - for (int i = 0; i < 10; i++) { - Festival festival = createFestival(LocalDate.of(2024, 10, 1), LocalDate.of(2024, 10, 10), sido.getId()); - em.persist(festival); - - FestivalBookmark bookmark = FestivalBookmark.builder() - .festivalId(festival.getId()) - .userId(otherUser.getId()) - .build(); - em.persist(bookmark); - } - - Pageable pageable = PageRequest.of(0, 6); - - // when - Page result = festivalRepository.findBookmarkedFestivals(currentUser.getId(), - pageable); - - // then - assertThat(result).isNotNull(); - assertThat(result.getTotalElements()).isEqualTo(30); - assertEquals(6, result.getSize()); - List content = result.getContent(); - for (FestivalInfoWithBookmark festivalInfoWithBookmark : content) { - assertThat(festivalInfoWithBookmark.getIsBookmarked()).isTrue(); - } - } - private static FestivalImage createFestivalImage(Festival festival) { return FestivalImage.builder() .festivalId(festival.getId()) diff --git a/src/test/java/com/odiga/fiesta/festival/service/FestivalServiceTest.java b/src/test/java/com/odiga/fiesta/festival/service/FestivalServiceTest.java index d745baf8..e417bdfb 100644 --- a/src/test/java/com/odiga/fiesta/festival/service/FestivalServiceTest.java +++ b/src/test/java/com/odiga/fiesta/festival/service/FestivalServiceTest.java @@ -422,8 +422,8 @@ void getFestival() { .collect(Collectors.toList()) ); - FestivalImage image1 = FestivalImage.builder().festivalId(festival.getId()).imageUrl("imageUrl1").build(); - FestivalImage image2 = FestivalImage.builder().festivalId(festival.getId()).imageUrl("imageUrl2").build(); + FestivalImage image1 = createFestivalImage(festival); + FestivalImage image2 = createFestivalImage(festival); List images = festivalImageRepository.saveAll(List.of(image1, image2)); @@ -840,6 +840,109 @@ private static FestivalBookmark createFestivalBookmark(Long festvialId, Long use .build(); } + @DisplayName("유저가 북마크한 페스티벌 조회 - 성공 케이스, 페스티벌이 하나의 이미지만 가지고 있음") + @Test + void findBookmarkedFestivals() { + // given + User currentUser = userRepository.save(createUser()); + + Festival festival = createFestival(); + Festival festival2 = createFestival(); + festivalRepository.saveAll(List.of(festival, festival2)); + + FestivalImage image = createFestivalImage(festival); + festivalImageRepository.save(image); + + FestivalBookmark bookmark = festivalBookmarkRepository.save( + createFestivalBookmark(festival.getId(), currentUser.getId())); + festivalBookmarkRepository.save(bookmark); + + int bookmarkCount = 1; + + // when + Page bookmarkedFestivals = festivalService.getBookmarkedFestivals(currentUser, + PageRequest.of(0, 5)); + + // then + assertThat(bookmarkedFestivals.getContent()) + .hasSize(1) + .extracting("festivalId", "thumbnailImage", "isBookmarked") + .containsExactly( + tuple(festival.getId(), image.getImageUrl(), true) + ); + + assertEquals(bookmarkedFestivals.getTotalElements(), bookmarkCount); + } + + @DisplayName("유저가 북마크한 페스티벌 조회 - 페스티벌의 이미지가 여러 개인 경우에도 첫 번째 이미지만 반환한다.") + @Test + void findBookmarkedFestivals_multipleFestivalImages() { + // given + User currentUser = userRepository.save(createUser()); + + Festival festival = createFestival(); + festivalRepository.save(festival); + + FestivalImage image1 = createFestivalImage(festival); + FestivalImage image2 = createFestivalImage(festival); + FestivalImage image3 = createFestivalImage(festival); + festivalImageRepository.saveAll(List.of(image1, image2, image3)); + + FestivalBookmark bookmark = festivalBookmarkRepository.save( + createFestivalBookmark(festival.getId(), currentUser.getId())); + festivalBookmarkRepository.save(bookmark); + + // when + Page bookmarkedFestivals = festivalService.getBookmarkedFestivals(currentUser, + PageRequest.of(0, 5)); + + // then + assertThat(bookmarkedFestivals.getContent()) + .hasSize(1) + .extracting("festivalId", "thumbnailImage", "isBookmarked") + .containsExactly( + tuple(festival.getId(), image1.getImageUrl(), true) + ); + } + + @DisplayName("유저가 북마크한 페스티벌 조회 - 성공, 북마크 한 페스티벌이 여러 개 일 때") + @Test + void findBookmarkedFestivals_Success() { + // given + User currentUser = userRepository.save(createUser()); + + Festival festival = createFestival(); + Festival festival2 = createFestival(); + Festival festival3 = createFestival(); + Festival festival4 = createFestival(); + Festival festival5 = createFestival(); + festivalRepository.saveAll(List.of(festival, festival2, festival3, festival4, festival5)); + + FestivalBookmark bookmark1 = festivalBookmarkRepository.save( + createFestivalBookmark(festival.getId(), currentUser.getId())); + FestivalBookmark bookmark2 = festivalBookmarkRepository.save( + createFestivalBookmark(festival.getId(), currentUser.getId())); + FestivalBookmark bookmark3 = festivalBookmarkRepository.save( + createFestivalBookmark(festival.getId(), currentUser.getId())); + + festivalBookmarkRepository.saveAll(List.of(bookmark1, bookmark2, bookmark3)); + + int pageSize = 2; + int bookmarkedFestivalCount = 3; + + // when + Page bookmarkedFestivals = festivalService.getBookmarkedFestivals(currentUser, + PageRequest.of(0, pageSize)); + + // then + assertThat(bookmarkedFestivals.getContent()).hasSize(pageSize); + assertThat(bookmarkedFestivals.getTotalElements()).isEqualTo(bookmarkedFestivalCount); + } + + private static FestivalImage createFestivalImage(Festival festival) { + return FestivalImage.builder().festivalId(festival.getId()).imageUrl("imageUrl1").build(); + } + private static Festival createFestival(LocalDate startDate, LocalDate endDate, Long sidoId) { return Festival.builder() .userId(1L) @@ -906,6 +1009,10 @@ private static Festival createFestival(String name, LocalDate currentDate, Doubl .build(); } + private static Festival createFestival() { + return createFestival("페스티벌 이름"); + } + private static Festival createFestival(String name) { return Festival.builder() .userId(1L) diff --git a/src/test/java/com/odiga/fiesta/user/service/UserServiceTest.java b/src/test/java/com/odiga/fiesta/user/service/UserServiceTest.java index c06d3ccf..131797d9 100644 --- a/src/test/java/com/odiga/fiesta/user/service/UserServiceTest.java +++ b/src/test/java/com/odiga/fiesta/user/service/UserServiceTest.java @@ -130,35 +130,6 @@ void createProfile_Success() { verify(userCompanionRepository).saveAll(anyList()); } - @DisplayName("유저가 북마크한 페스티벌들을 조회") - @Test - void getBookmarkedFestivals() { - // given - User currentUser = createNoProfileUser(); - given(userRepository.existsById(currentUser.getId())).willReturn(true); - - Pageable pageable = PageRequest.of(0, 5); - List festivals = Arrays.asList( - new FestivalInfoWithBookmark(1L, "Festival 1", "Sido 1", "Sigungu 1", "image1.jpg", - LocalDate.of(2024, 10, 1), LocalDate.of(2024, 10, 10), true), - new FestivalInfoWithBookmark(2L, "Festival 2", "Sido 2", "Sigungu 2", "image2.jpg", - LocalDate.of(2024, 10, 2), LocalDate.of(2024, 10, 11), true) - ); - - Page festivalPage = new PageImpl<>(festivals, pageable, festivals.size()); - given(festivalRepository.findBookmarkedFestivals(currentUser.getId(), pageable)).willReturn(festivalPage); - - // when - Page result = userService.getBookmarkedFestivals(currentUser, pageable); - - // then - assertThat(result).isNotNull(); // 반환된 값이 null이 아닌지 확인 - assertThat(result.getTotalElements()).isEqualTo(2); // 총 북마크된 페스티벌 수 확인 - assertThat(result.getContent()) - .usingRecursiveComparison() - .isEqualTo(festivals); - } - @DisplayName("유저 정보 수정 - 성공") @Test void updateUserInfo_Success() {