From e91267e9c1505a004d2971c687360ac275ca188a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Sun, 17 Nov 2024 14:48:12 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20marker=20=EC=82=AD=EC=A0=9C=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../findy_be/common/exception/ErrorCode.java | 2 ++ .../findy_be/marker/api/MarkerController.java | 13 +++++-- .../application/delete/DeleteMarker.java | 6 ++++ .../delete/DeleteMarkerService.java | 34 +++++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarker.java create mode 100644 src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarkerService.java diff --git a/src/main/java/org/findy/findy_be/common/exception/ErrorCode.java b/src/main/java/org/findy/findy_be/common/exception/ErrorCode.java index d20b69d..47bd555 100644 --- a/src/main/java/org/findy/findy_be/common/exception/ErrorCode.java +++ b/src/main/java/org/findy/findy_be/common/exception/ErrorCode.java @@ -24,10 +24,12 @@ public enum ErrorCode { // 403 error, AUTHENTICATION_EXCEPTION_ERROR(FORBIDDEN, "Authentication Content-Type not supported: %s"), FORBIDDEN_BOOKMARK_ACCESS(FORBIDDEN, "해당 즐겨찾기에 접근할 권한이 없습니다."), + FORBIDDEN_MARKER_ACCESS(FORBIDDEN, "해당 마커에 접근할 권한이 없습니다."), // 404 error NOT_FOUND_EMAIL(NOT_FOUND, "해당 이메일이 존재하지 않습니다."), NOT_FOUND_BOOKMARK_BY_ID(NOT_FOUND, "해당 id : %s의 즐겨찾기가 존재하지 않습니다."), + NOT_FOUND_MARKER_BY_ID(NOT_FOUND, "해당 id : %s의 마커가 존재하지 않습니다."), NOT_FOUND_USER(NOT_FOUND, "해당 이메일을 가진 유저가 존재하지 않습니다."), NOT_FOUND_USER_BY_ID(NOT_FOUND, "해당 id : %s를 가진 유저가 존재하지 않습니다."), BAD_REQUEST_CATEGORY_NOT_FOUND_ERROR(NOT_FOUND, "해당 input : %s을 가진 카테고리가 없습니다."), diff --git a/src/main/java/org/findy/findy_be/marker/api/MarkerController.java b/src/main/java/org/findy/findy_be/marker/api/MarkerController.java index 500217d..f469cbd 100644 --- a/src/main/java/org/findy/findy_be/marker/api/MarkerController.java +++ b/src/main/java/org/findy/findy_be/marker/api/MarkerController.java @@ -4,11 +4,13 @@ import org.findy.findy_be.common.dto.pagination.response.SliceResponse; import org.findy.findy_be.common.meta.LoginUser; import org.findy.findy_be.marker.api.swagger.MarkerAPIPresentation; +import org.findy.findy_be.marker.application.delete.DeleteMarker; import org.findy.findy_be.marker.application.find.FindAllPagedMarkers; import org.findy.findy_be.marker.application.register.RegisterMarker; import org.findy.findy_be.marker.dto.request.RegisterSearchedMarkerRequest; -import org.findy.findy_be.place.dto.response.PlaceResponse; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.findy.findy_be.user.domain.User; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; @@ -27,6 +29,7 @@ public class MarkerController implements MarkerAPIPresentation { private final RegisterMarker registerMarker; private final FindAllPagedMarkers findAllPagedMarkers; + private final DeleteMarker deleteMarker; @PostMapping("/{bookmarkId}") public void registerMarker(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId, @@ -35,8 +38,14 @@ public void registerMarker(@LoginUser User user, @PathVariable("bookmarkId") Lon } @GetMapping("/{bookmarkId}") - public SliceResponse getMarkers(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId, + public SliceResponse getMarkers(@LoginUser User user, + @PathVariable("bookmarkId") Long bookmarkId, @ModelAttribute PagedRequest request) { return findAllPagedMarkers.invoke(user.getUserId(), bookmarkId, request.cursor(), request.size()); } + + @DeleteMapping("/{id}") + public void deleteMarker(@LoginUser User user, @PathVariable("id") Long markerId) { + deleteMarker.invoke(user.getUserId(), markerId); + } } diff --git a/src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarker.java b/src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarker.java new file mode 100644 index 0000000..9146d3a --- /dev/null +++ b/src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarker.java @@ -0,0 +1,6 @@ +package org.findy.findy_be.marker.application.delete; + +public interface DeleteMarker { + + void invoke(String userId, Long markerId); +} diff --git a/src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarkerService.java b/src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarkerService.java new file mode 100644 index 0000000..90f3582 --- /dev/null +++ b/src/main/java/org/findy/findy_be/marker/application/delete/DeleteMarkerService.java @@ -0,0 +1,34 @@ +package org.findy.findy_be.marker.application.delete; + +import static org.findy.findy_be.common.exception.ErrorCode.*; + +import org.findy.findy_be.marker.domain.Marker; +import org.findy.findy_be.marker.repository.MarkerRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import jakarta.persistence.EntityNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@Transactional +@RequiredArgsConstructor +public class DeleteMarkerService implements DeleteMarker { + + private final MarkerRepository markerRepository; + + public void invoke(String userId, Long markerId) { + + Marker marker = markerRepository.findById(markerId) + .orElseThrow( + () -> new EntityNotFoundException(String.format(NOT_FOUND_MARKER_BY_ID.getMessage(), markerId))); + validateMarkerUser(userId, marker); + markerRepository.delete(marker); + } + + private static void validateMarkerUser(final String userId, final Marker marker) { + if (!marker.getBookmark().getUser().getUserId().equals(userId)) { + throw new IllegalArgumentException(FORBIDDEN_MARKER_ACCESS.getMessage()); + } + } +} From b04054b5b3a163c55ae80ff59798ceb4dac464f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Sun, 17 Nov 2024 14:48:28 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20marker=20=EC=82=AD=EC=A0=9C=20API?= =?UTF-8?q?=20swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../marker/api/swagger/MarkerAPIPresentation.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/findy/findy_be/marker/api/swagger/MarkerAPIPresentation.java b/src/main/java/org/findy/findy_be/marker/api/swagger/MarkerAPIPresentation.java index 82f1238..428a135 100644 --- a/src/main/java/org/findy/findy_be/marker/api/swagger/MarkerAPIPresentation.java +++ b/src/main/java/org/findy/findy_be/marker/api/swagger/MarkerAPIPresentation.java @@ -6,7 +6,7 @@ import org.findy.findy_be.common.meta.CustomApiResponses; import org.findy.findy_be.common.meta.LoginUser; import org.findy.findy_be.marker.dto.request.RegisterSearchedMarkerRequest; -import org.findy.findy_be.place.dto.response.PlaceResponse; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.findy.findy_be.user.domain.User; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; @@ -40,6 +40,17 @@ void registerMarker(@LoginUser User user, @PathVariable Long bookmarkId, @CustomApiResponse(error = "IllegalArgumentException", status = 400, message = "잘못된 요청입니다.", description = "잘못된 쿼리 파라미터가 포함된 경우"), @CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "서버 내부에서 예기치 않은 오류가 발생한 경우") }) - SliceResponse getMarkers(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId, + SliceResponse getMarkers(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId, @ModelAttribute PagedRequest request); + + @Operation(summary = "마커 삭제", description = "마커를 삭제하는 API", responses = { + @ApiResponse(responseCode = "200", description = "마커 삭제 성공") + }) + @CustomApiResponses({ + @CustomApiResponse(error = "IllegalArgumentException", status = 400, message = "잘못된 요청입니다.", description = "잘못된 쿼리 파라미터가 포함된 경우"), + @CustomApiResponse(error = "ForbiddenAccessException", status = 403, message = "해당 마커에 접근할 권한이 없습니다.", description = "권한이 없는 유저가 즐겨찾기에 접근할 경우"), + @CustomApiResponse(error = "EntityNotFoundException", status = 404, message = "해당 id : {id}의 마커가 존재하지 않습니다.", description = "존재하지 않는 마커에 접근할 경우"), + @CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "서버 내부에서 예기치 않은 오류가 발생한 경우") + }) + void deleteMarker(@LoginUser User user, @PathVariable("id") Long markerId); } From 2f085db5077d3a2241d4fdc0eb5940af2687a33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Sun, 17 Nov 2024 14:49:49 +0900 Subject: [PATCH 3/4] =?UTF-8?q?test:=20marker=20=EC=82=AD=EC=A0=9C=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../marker/api/MarkerControllerTest.java | 23 ++++++ .../delete/DeleteMarkerServiceTest.java | 79 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 src/test/java/org/findy/findy_be/marker/application/delete/DeleteMarkerServiceTest.java diff --git a/src/test/java/org/findy/findy_be/marker/api/MarkerControllerTest.java b/src/test/java/org/findy/findy_be/marker/api/MarkerControllerTest.java index d17b76e..c3dae88 100644 --- a/src/test/java/org/findy/findy_be/marker/api/MarkerControllerTest.java +++ b/src/test/java/org/findy/findy_be/marker/api/MarkerControllerTest.java @@ -6,9 +6,11 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.assertj.core.api.Assertions; import org.findy.findy_be.auth.oauth.domain.SocialProviderType; import org.findy.findy_be.auth.oauth.domain.UserPrincipal; import org.findy.findy_be.bookmark.domain.Bookmark; @@ -25,6 +27,7 @@ import org.findy.findy_be.user.domain.RoleType; import org.findy.findy_be.user.domain.User; import org.findy.findy_be.user.repository.UserRepository; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -198,6 +201,21 @@ void setUp() { .andExpect(jsonPath("$.nextCursor").doesNotExist()); } + @DisplayName("[성공] 마커 삭제 요청") + @Test + void 마커_삭제_요청() throws Exception { + // given + initPlacesForBookmark(testBookmark, 1); + Long markerId = markerRepository.findAll().get(0).getId(); + + // when + DeleteMarker(markerId); + + // then + Optional resultMarker = markerRepository.findById(markerId); + Assertions.assertThat(resultMarker.isEmpty()).isTrue(); + } + private ResultActions GetBookmarks(final Long bookmarkId, final PagedRequest pagedRequest) throws Exception { return mvc.perform((get("/api/markers/{bookmarkId}", bookmarkId) .param("cursor", pagedRequest.cursor() == null ? "" : pagedRequest.cursor().toString()) @@ -215,6 +233,11 @@ private ResultActions PostSearchedPlace(final Long bookmarkId, .andDo(print()); } + private @NotNull ResultActions DeleteMarker(Long id) throws Exception { + return mvc.perform(delete("/api/markers/{id}", id)) + .andDo(print()); + } + private void initPlacesForBookmark(Bookmark bookmark, int count) { List places = IntStream.range(1, count + 1) .mapToObj(i -> new RegisterSearchedMarkerRequest( diff --git a/src/test/java/org/findy/findy_be/marker/application/delete/DeleteMarkerServiceTest.java b/src/test/java/org/findy/findy_be/marker/application/delete/DeleteMarkerServiceTest.java new file mode 100644 index 0000000..fc6bd3b --- /dev/null +++ b/src/test/java/org/findy/findy_be/marker/application/delete/DeleteMarkerServiceTest.java @@ -0,0 +1,79 @@ +package org.findy.findy_be.marker.application.delete; + +import static org.findy.findy_be.common.exception.ErrorCode.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.findy.findy_be.bookmark.domain.Bookmark; +import org.findy.findy_be.common.MockTest; +import org.findy.findy_be.marker.domain.Marker; +import org.findy.findy_be.marker.repository.MarkerRepository; +import org.findy.findy_be.place.domain.Place; +import org.findy.findy_be.user.domain.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +class DeleteMarkerServiceTest extends MockTest { + + @Mock + private MarkerRepository markerRepository; + + @InjectMocks + private DeleteMarkerService deleteMarkerService; + + private User testUser; + private Bookmark bookmark; + private Place place; + private Marker marker; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + testUser = mock(User.class); + when(testUser.getUserId()).thenReturn("N49sfgdahdKz_fp-223424er1N3D6kd"); + + bookmark = mock(Bookmark.class); + when(bookmark.getUser()).thenReturn(testUser); + + place = mock(Place.class); + + marker = Marker.createForCustomBookmark(bookmark, place); + } + + @DisplayName("[성공] 마커 삭제") + @Test + public void 마커_삭제() throws Exception { + // given + Long markerId = 1L; + String userId = testUser.getUserId(); + when(markerRepository.findById(markerId)).thenReturn(Optional.of(marker)); + + // when + deleteMarkerService.invoke(userId, markerId); + + // then + verify(markerRepository, times(1)).delete(marker); + } + + @DisplayName("[실패] 다른 유저의 마커 삭제 시도") + @Test + void 마커_삭제_실패_다른유저() { + // given + Long markerId = 1L; + String userId = "differentUserId"; + when(markerRepository.findById(markerId)).thenReturn(Optional.of(marker)); + + // when & then + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> deleteMarkerService.invoke(userId, markerId)); + + assertEquals(FORBIDDEN_MARKER_ACCESS.getMessage(), exception.getMessage()); + } +} From aa18a4a50076d432842b17a93c74c71d03bfbd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Sun, 17 Nov 2024 14:50:16 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20marker=20=EC=A1=B0=ED=9A=8C=20r?= =?UTF-8?q?esponse=20=EC=8B=9C=EC=97=90=20markerId=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/find/FindAllPagedMarkers.java | 5 ++- .../find/FindAllPagedMarkersService.java | 14 +++--- ...Response.java => MarkerPlaceResponse.java} | 10 ++--- .../repository/PlaceRepositoryCustom.java | 5 ++- .../repository/PlaceRepositoryCustomImpl.java | 23 +++++++--- .../find/FindAllPagedMarkersServiceTest.java | 45 +++++++++---------- .../PlaceRepositoryCustomImplTest.java | 29 +++++++----- 7 files changed, 72 insertions(+), 59 deletions(-) rename src/main/java/org/findy/findy_be/place/dto/response/{PlaceResponse.java => MarkerPlaceResponse.java} (64%) diff --git a/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkers.java b/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkers.java index 3a13ae8..f04842c 100644 --- a/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkers.java +++ b/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkers.java @@ -1,8 +1,9 @@ package org.findy.findy_be.marker.application.find; import org.findy.findy_be.common.dto.pagination.response.SliceResponse; -import org.findy.findy_be.place.dto.response.PlaceResponse; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; public interface FindAllPagedMarkers { - SliceResponse invoke(final String userId, final Long bookmarkId, final Long cursor, final int size); + SliceResponse invoke(final String userId, final Long bookmarkId, final Long cursor, + final int size); } diff --git a/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersService.java b/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersService.java index a8b7d07..0fd4aa4 100644 --- a/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersService.java +++ b/src/main/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersService.java @@ -3,8 +3,7 @@ import java.util.List; import org.findy.findy_be.common.dto.pagination.response.SliceResponse; -import org.findy.findy_be.place.domain.Place; -import org.findy.findy_be.place.dto.response.PlaceResponse; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.findy.findy_be.place.repository.PlaceRepository; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -21,15 +20,14 @@ public class FindAllPagedMarkersService implements FindAllPagedMarkers { private final PlaceRepository placeRepository; - public SliceResponse invoke(final String userId, final Long bookmarkId, final Long cursor, + public SliceResponse invoke(final String userId, final Long bookmarkId, final Long cursor, final int size) { Pageable pageable = PageRequest.of(0, size); - Slice placeSlice = placeRepository.findPlacesByUserIdAndBookmarkId(userId, bookmarkId, pageable, cursor); + Slice placeSlice = placeRepository.findPlacesByUserIdAndBookmarkId(userId, bookmarkId, + pageable, cursor); - List data = placeSlice.stream() - .map(PlaceResponse::from) - .toList(); - Long nextCursor = placeSlice.hasNext() ? data.get(data.size() - 1).placeId() : null; + List data = placeSlice.getContent(); + Long nextCursor = placeSlice.hasNext() ? data.get(data.size() - 1).markerId() : null; return new SliceResponse<>(data, cursor != null ? cursor.intValue() : 0, size, placeSlice.hasNext(), nextCursor); diff --git a/src/main/java/org/findy/findy_be/place/dto/response/PlaceResponse.java b/src/main/java/org/findy/findy_be/place/dto/response/MarkerPlaceResponse.java similarity index 64% rename from src/main/java/org/findy/findy_be/place/dto/response/PlaceResponse.java rename to src/main/java/org/findy/findy_be/place/dto/response/MarkerPlaceResponse.java index 16726d5..7eceb73 100644 --- a/src/main/java/org/findy/findy_be/place/dto/response/PlaceResponse.java +++ b/src/main/java/org/findy/findy_be/place/dto/response/MarkerPlaceResponse.java @@ -6,15 +6,15 @@ import lombok.Builder; @Builder -public record PlaceResponse( - Long placeId, +public record MarkerPlaceResponse( + Long markerId, String title, String address, Category category ) { - public static PlaceResponse from(final Place place) { - return PlaceResponse.builder() - .placeId(place.getId()) + public static MarkerPlaceResponse of(final Long markerId, final Place place) { + return MarkerPlaceResponse.builder() + .markerId(markerId) .title(place.getTitle()) .address(place.getAddress()) .category(place.getCategory()) diff --git a/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustom.java b/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustom.java index d0676e5..bfb3a2d 100644 --- a/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustom.java +++ b/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustom.java @@ -1,10 +1,11 @@ package org.findy.findy_be.place.repository; -import org.findy.findy_be.place.domain.Place; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; public interface PlaceRepositoryCustom { - Slice findPlacesByUserIdAndBookmarkId(String userId, Long bookmarkId, Pageable pageable, Long cursor); + Slice findPlacesByUserIdAndBookmarkId(String userId, Long bookmarkId, Pageable pageable, + Long cursor); } diff --git a/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImpl.java b/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImpl.java index 6c59284..555076b 100644 --- a/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImpl.java +++ b/src/main/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImpl.java @@ -1,16 +1,18 @@ package org.findy.findy_be.place.repository; import java.util.List; +import java.util.Objects; import org.findy.findy_be.bookmark.domain.QBookmark; import org.findy.findy_be.marker.domain.QMarker; -import org.findy.findy_be.place.domain.Place; import org.findy.findy_be.place.domain.QPlace; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; import org.springframework.stereotype.Repository; +import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -22,14 +24,14 @@ public class PlaceRepositoryCustomImpl implements PlaceRepositoryCustom { private final JPAQueryFactory queryFactory; @Override - public Slice findPlacesByUserIdAndBookmarkId(String userId, Long bookmarkId, Pageable pageable, + public Slice findPlacesByUserIdAndBookmarkId(String userId, Long bookmarkId, Pageable pageable, Long cursor) { QBookmark bookmark = QBookmark.bookmark; QMarker marker = QMarker.marker; QPlace place = QPlace.place; - List places = queryFactory - .select(place) + List results = queryFactory + .select(marker.id, place) .from(bookmark) .join(bookmark.markers, marker) .join(marker.place, place) @@ -40,11 +42,18 @@ public Slice findPlacesByUserIdAndBookmarkId(String userId, Long bookmark .limit(pageable.getPageSize() + 1) .fetch(); - boolean hasNext = places.size() > pageable.getPageSize(); + List responses = results.stream() + .map(tuple -> MarkerPlaceResponse.of( + tuple.get(marker.id), + Objects.requireNonNull(tuple.get(place)) + )) + .toList(); + + boolean hasNext = responses.size() > pageable.getPageSize(); if (hasNext) { - places = places.subList(0, pageable.getPageSize()); + responses = responses.subList(0, pageable.getPageSize()); } - return new SliceImpl<>(places, pageable, hasNext); + return new SliceImpl<>(responses, pageable, hasNext); } } diff --git a/src/test/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersServiceTest.java b/src/test/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersServiceTest.java index 4a4ab6b..abb9713 100644 --- a/src/test/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersServiceTest.java +++ b/src/test/java/org/findy/findy_be/marker/application/find/FindAllPagedMarkersServiceTest.java @@ -9,12 +9,10 @@ import org.findy.findy_be.common.MockTest; import org.findy.findy_be.common.dto.pagination.response.SliceResponse; -import org.findy.findy_be.marker.dto.request.CategoryRequest; -import org.findy.findy_be.marker.dto.request.RegisterYouTubeMarkerRequest; import org.findy.findy_be.place.domain.MajorCategory; import org.findy.findy_be.place.domain.MiddleCategory; -import org.findy.findy_be.place.domain.Place; -import org.findy.findy_be.place.dto.response.PlaceResponse; +import org.findy.findy_be.place.domain.vo.Category; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.findy.findy_be.place.repository.PlaceRepository; import org.findy.findy_be.user.domain.User; import org.junit.jupiter.api.BeforeEach; @@ -37,26 +35,21 @@ class FindAllPagedMarkersServiceTest extends MockTest { private FindAllPagedMarkersService findAllPagedMarkersService; private User testUser; - private List places; + private List markerPlaceResponses; @BeforeEach public void setUp() throws Exception { MockitoAnnotations.openMocks(this); testUser = mock(User.class); - CategoryRequest categoryRequest = new CategoryRequest(MajorCategory.RESTAURANT, MiddleCategory.KOREAN); - places = IntStream.range(0, 5) - .mapToObj(i -> new RegisterYouTubeMarkerRequest( - "Test Place " + i, - "Description " + i, - "02-1234-5678", - "Seoul Road " + i, - categoryRequest, - "1269827323", - "375719345", - "02-000-000", - "0.04" - )) - .map(Place::create) + + Category category = Category.of(MajorCategory.RESTAURANT, MiddleCategory.KOREAN); + markerPlaceResponses = IntStream.range(0, 5) + .mapToObj(i -> MarkerPlaceResponse.builder() + .markerId((long)i) + .title("Test Place " + i) + .address("Seoul Road " + i) + .category(category) + .build()) .collect(Collectors.toList()); } @@ -66,7 +59,7 @@ public void setUp() throws Exception { // given Long bookmarkId = 1L; Pageable pageable = PageRequest.of(0, 3); - Slice placeSlice = new SliceImpl<>(places.subList(0, 3), pageable, true); + Slice placeSlice = new SliceImpl<>(markerPlaceResponses.subList(0, 3), pageable, true); when(placeRepository.findPlacesByUserIdAndBookmarkId(eq(testUser.getUserId()), eq(bookmarkId), any(Pageable.class), @@ -74,12 +67,13 @@ public void setUp() throws Exception { .thenReturn(placeSlice); // when - SliceResponse response = findAllPagedMarkersService.invoke(testUser.getUserId(), 1L, 0L, 3); + SliceResponse response = findAllPagedMarkersService.invoke(testUser.getUserId(), 1L, 0L, + 3); // then assertThat(response.data().size()).isEqualTo(3); assertThat(response.hasNext()).isTrue(); - assertThat(response.nextCursor()).isEqualTo(places.get(2).getId()); + assertThat(response.nextCursor()).isEqualTo(markerPlaceResponses.get(2).markerId()); } @DisplayName("[성공 case2(다음페이지 없음)] 유저 마커 조회 성공") @@ -88,7 +82,7 @@ public void setUp() throws Exception { // given Long bookmarkId = 1L; Pageable pageable = PageRequest.of(0, 3); - Slice placeSlice = new SliceImpl<>(places.subList(0, 3), pageable, false); + Slice placeSlice = new SliceImpl<>(markerPlaceResponses.subList(0, 3), pageable, false); when(placeRepository.findPlacesByUserIdAndBookmarkId(eq(testUser.getUserId()), eq(bookmarkId), any(Pageable.class), @@ -96,11 +90,12 @@ public void setUp() throws Exception { .thenReturn(placeSlice); // when - SliceResponse response = findAllPagedMarkersService.invoke(testUser.getUserId(), 1L, 0L, 3); + SliceResponse response = findAllPagedMarkersService.invoke(testUser.getUserId(), 1L, 0L, + 3); // then assertThat(response.data().size()).isEqualTo(3); assertThat(response.hasNext()).isFalse(); assertThat(response.nextCursor()).isNull(); } -} \ No newline at end of file +} diff --git a/src/test/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImplTest.java b/src/test/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImplTest.java index d180ab3..ea2b6ae 100644 --- a/src/test/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImplTest.java +++ b/src/test/java/org/findy/findy_be/place/repository/PlaceRepositoryCustomImplTest.java @@ -18,6 +18,7 @@ import org.findy.findy_be.place.domain.MajorCategory; import org.findy.findy_be.place.domain.MiddleCategory; import org.findy.findy_be.place.domain.Place; +import org.findy.findy_be.place.dto.response.MarkerPlaceResponse; import org.findy.findy_be.user.domain.RoleType; import org.findy.findy_be.user.domain.User; import org.findy.findy_be.user.repository.UserRepository; @@ -48,7 +49,6 @@ class PlaceRepositoryCustomImplTest extends RepositoryTest { private User testUser; private Bookmark testBookmark; - private List persistPlaces; @BeforeEach void setUp() { @@ -71,18 +71,22 @@ void setUp() { initPlacesForBookmark(testBookmark, 10); } - @DisplayName("[성공 (다음 페이지가 있는 경우)]유저의 특정 북마크에 저장된 장소 목록을 페이징 조회") + @DisplayName("[성공 (다음 페이지가 있는 경우)] 유저의 특정 북마크에 저장된 장소 목록을 페이징 조회") @Test void 유저_북마크_장소_조회_성공_case1() { Pageable pageable = PageRequest.of(0, 5); Long cursor = 0L; - Slice placeSlice = placeRepository.findPlacesByUserIdAndBookmarkId(testUser.getUserId(), - testBookmark.getId(), pageable, cursor); + Slice placeSlice = placeRepository.findPlacesByUserIdAndBookmarkId( + testUser.getUserId(), + testBookmark.getId(), + pageable, + cursor + ); assertThat(placeSlice.getContent()).hasSize(5); assertThat(placeSlice.hasNext()).isTrue(); - assertThat(placeSlice.getContent().get(0).getTitle()).isEqualTo("Test Place 1"); + assertThat(placeSlice.getContent().get(0).title()).isEqualTo("Test Place 1"); } @DisplayName("[성공 (마지막 페이지)] 유저의 특정 북마크에 저장된 장소 목록을 페이징 조회") @@ -91,11 +95,16 @@ void setUp() { Pageable pageable = PageRequest.of(0, 11); Long cursor = 0L; - Slice placeSlice = placeRepository.findPlacesByUserIdAndBookmarkId(testUser.getUserId(), - testBookmark.getId(), pageable, cursor); + Slice placeSlice = placeRepository.findPlacesByUserIdAndBookmarkId( + testUser.getUserId(), + testBookmark.getId(), + pageable, + cursor + ); + assertThat(placeSlice.getContent()).hasSize(10); assertThat(placeSlice.hasNext()).isFalse(); - assertThat(placeSlice.getContent().get(0).getTitle()).isEqualTo("Test Place 1"); + assertThat(placeSlice.getContent().get(0).title()).isEqualTo("Test Place 1"); } private void initPlacesForBookmark(Bookmark bookmark, int count) { @@ -113,9 +122,9 @@ private void initPlacesForBookmark(Bookmark bookmark, int count) { ))) .collect(Collectors.toList()); - persistPlaces = placeJpaRepository.saveAll(places); + List persistPlaces = placeJpaRepository.saveAll(places); - List markers = places.stream() + List markers = persistPlaces.stream() .map(place -> Marker.createForCustomBookmark(bookmark, place)) .collect(Collectors.toList());